fix: expose promoted template media slots

This commit is contained in:
James
2026-08-25 05:33:50 +00:00
parent a562946e11
commit 1e11608d44
27 changed files with 1336 additions and 188 deletions
+387 -35
View File
@@ -10,7 +10,7 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
previewSrc="/public/catalog/blocks/message-thread-reveal.json"
compositionId="message-thread-reveal"
compositionSrc="compositions/message-thread-reveal.html"
variables={[{"id":"contactName","type":"string","role":"content","label":"Contact name","description":"Name pill in the chat header; the avatar shows its first letter.","default":"Rachel"},{"id":"cardTitle","type":"string","role":"content","label":"Link card title","description":"Title on the shared link card.","default":"HyperFrames | Write HTML, render pixel-perfect video"},{"id":"cardDomain","type":"string","role":"content","label":"Link card domain","description":"Domain line under the card title.","default":"hyperframes.heygen.com"},{"id":"ecProof","type":"string","role":"content","label":"End-card proof","description":"Social-proof line under the stars.","default":"12,000+ creators"},{"id":"ecCta","type":"string","role":"content","label":"End-card CTA","description":"Label on the closing card button.","default":"Start rendering free"}]}
variables={[{"id":"contactName","type":"string","role":"content","label":"Contact name","description":"Name pill in the chat header; the avatar shows its first letter.","default":"Rachel"},{"id":"questionMessage","type":"string","role":"content","label":"Opening question","description":"First incoming message that establishes what the conversation is about.","default":"what r u using for the launch video??"},{"id":"teaserMessage","type":"string","role":"content","label":"Teaser reply","description":"First typed outgoing reply before the shared link card.","default":"wait look 👀"},{"id":"cardImage","type":"image","role":"content","label":"Link card image","description":"Preview image on the shared link card.","default":"assets/card-image.jpg"},{"id":"cardTitle","type":"string","role":"content","label":"Link card title","description":"Title on the shared link card.","default":"HyperFrames | Write HTML, render pixel-perfect video"},{"id":"cardDomain","type":"string","role":"content","label":"Link card domain","description":"Domain line under the card title.","default":"hyperframes.heygen.com"},{"id":"reactionMessage","type":"string","role":"content","label":"Link reaction","description":"Incoming reaction immediately after the shared link.","default":"OMG IT'S HTML"},{"id":"reactionEmoji","type":"string","role":"content","label":"Reaction emoji","description":"Emoji-only reaction after the shared link.","default":"🤯🤯🤯"},{"id":"benefitMessage","type":"string","role":"content","label":"Benefit reply","description":"Typed outgoing reply that names the primary benefit.","default":"renders in 4K. no editor"},{"id":"discoveryMessage","type":"string","role":"content","label":"Discovery question","description":"Incoming question asking where the product was found.","default":"where did u find this"},{"id":"sourceMessage","type":"string","role":"content","label":"Source reply","description":"Typed outgoing reply naming where to find the product.","default":"on heygen"},{"id":"workflowMessage","type":"string","role":"content","label":"Workflow reply","description":"Typed outgoing reply describing how the product works.","default":"u just write plain html tags"},{"id":"ownershipMessage","type":"string","role":"content","label":"Ownership reply","description":"Typed outgoing reply that closes the product explanation.","default":"the code is yours forever"},{"id":"installMessage","type":"string","role":"content","label":"Intent reply","description":"Incoming message expressing intent to try the product.","default":"installing rn"},{"id":"thanksMessage","type":"string","role":"content","label":"Closing reply","description":"Final incoming message in the conversation.","default":"ty bestie 💚"},{"id":"brandLogo","type":"image","role":"content","label":"Brand logo","description":"Transparent horizontal wordmark on the closing card.","default":"assets/hyperframes-logo-black.svg"},{"id":"ecProof","type":"string","role":"content","label":"End-card proof","description":"Social-proof line under the stars.","default":"12,000+ creators"},{"id":"ecFeature1","type":"string","role":"content","label":"End-card feature 1","description":"First two-line benefit; use | to break the line.","default":"Write|plain HTML"},{"id":"ecFeature2","type":"string","role":"content","label":"End-card feature 2","description":"Second two-line benefit; use | to break the line.","default":"Render|pixel-perfect"},{"id":"ecFeature3","type":"string","role":"content","label":"End-card feature 3","description":"Third two-line benefit; use | to break the line.","default":"Own|every line"},{"id":"ecCta","type":"string","role":"content","label":"End-card CTA","description":"Label on the closing card button.","default":"Start rendering free"}]}
>
```html message-thread-reveal.html
@@ -19,9 +19,25 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
lang="en"
data-composition-variables='[
{ "id": "contactName", "type": "string", "role": "content", "label": "Contact name", "description": "Name pill in the chat header; the avatar shows its first letter.", "default": "Rachel" },
{ "id": "questionMessage", "type": "string", "role": "content", "label": "Opening question", "description": "First incoming message that establishes what the conversation is about.", "default": "what r u using for the launch video??" },
{ "id": "teaserMessage", "type": "string", "role": "content", "label": "Teaser reply", "description": "First typed outgoing reply before the shared link card.", "default": "wait look 👀" },
{ "id": "cardImage", "type": "image", "role": "content", "label": "Link card image", "description": "Preview image on the shared link card.", "default": "assets/card-image.jpg" },
{ "id": "cardTitle", "type": "string", "role": "content", "label": "Link card title", "description": "Title on the shared link card.", "default": "HyperFrames | Write HTML, render pixel-perfect video" },
{ "id": "cardDomain", "type": "string", "role": "content", "label": "Link card domain", "description": "Domain line under the card title.", "default": "hyperframes.heygen.com" },
{ "id": "reactionMessage", "type": "string", "role": "content", "label": "Link reaction", "description": "Incoming reaction immediately after the shared link.", "default": "OMG IT'S HTML" },
{ "id": "reactionEmoji", "type": "string", "role": "content", "label": "Reaction emoji", "description": "Emoji-only reaction after the shared link.", "default": "🤯🤯🤯" },
{ "id": "benefitMessage", "type": "string", "role": "content", "label": "Benefit reply", "description": "Typed outgoing reply that names the primary benefit.", "default": "renders in 4K. no editor" },
{ "id": "discoveryMessage", "type": "string", "role": "content", "label": "Discovery question", "description": "Incoming question asking where the product was found.", "default": "where did u find this" },
{ "id": "sourceMessage", "type": "string", "role": "content", "label": "Source reply", "description": "Typed outgoing reply naming where to find the product.", "default": "on heygen" },
{ "id": "workflowMessage", "type": "string", "role": "content", "label": "Workflow reply", "description": "Typed outgoing reply describing how the product works.", "default": "u just write plain html tags" },
{ "id": "ownershipMessage", "type": "string", "role": "content", "label": "Ownership reply", "description": "Typed outgoing reply that closes the product explanation.", "default": "the code is yours forever" },
{ "id": "installMessage", "type": "string", "role": "content", "label": "Intent reply", "description": "Incoming message expressing intent to try the product.", "default": "installing rn" },
{ "id": "thanksMessage", "type": "string", "role": "content", "label": "Closing reply", "description": "Final incoming message in the conversation.", "default": "ty bestie 💚" },
{ "id": "brandLogo", "type": "image", "role": "content", "label": "Brand logo", "description": "Transparent horizontal wordmark on the closing card.", "default": "assets/hyperframes-logo-black.svg" },
{ "id": "ecProof", "type": "string", "role": "content", "label": "End-card proof", "description": "Social-proof line under the stars.", "default": "12,000+ creators" },
{ "id": "ecFeature1", "type": "string", "role": "content", "label": "End-card feature 1", "description": "First two-line benefit; use | to break the line.", "default": "Write|plain HTML" },
{ "id": "ecFeature2", "type": "string", "role": "content", "label": "End-card feature 2", "description": "Second two-line benefit; use | to break the line.", "default": "Render|pixel-perfect" },
{ "id": "ecFeature3", "type": "string", "role": "content", "label": "End-card feature 3", "description": "Third two-line benefit; use | to break the line.", "default": "Own|every line" },
{ "id": "ecCta", "type": "string", "role": "content", "label": "End-card CTA", "description": "Label on the closing card button.", "default": "Start rendering free" }
]'
>
@@ -572,7 +588,14 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-occlusion
>
<div class="pop pop-recv">
<div class="bubble recv">what r u using for the launch video??</div>
<div
class="bubble recv"
id="mtr-message-question"
data-layout-allow-overlap
data-layout-allow-occlusion
>
what r u using for the launch video??
</div>
</div>
</div>
<div
@@ -600,7 +623,14 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-occlusion
>
<div class="pop pop-sent">
<div class="bubble sent tail-sent">wait look 👀</div>
<div
class="bubble sent tail-sent"
id="mtr-message-teaser"
data-layout-allow-overlap
data-layout-allow-occlusion
>
wait look 👀
</div>
<div class="delivered">Delivered</div>
</div>
</div>
@@ -613,7 +643,12 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
>
<div class="pop pop-sent">
<div class="card">
<img class="cardimg" src="assets/card-image.jpg" alt="" />
<img
class="cardimg"
data-var-src="cardImage"
src="assets/card-image.jpg"
alt=""
/>
<div class="cardmeta">
<div class="cardtxt">
<div class="cardtitle">
@@ -633,7 +668,16 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-recv"><div class="bubble recv">OMG IT&#39;S HTML</div></div>
<div class="pop pop-recv">
<div
class="bubble recv"
id="mtr-message-reaction"
data-layout-allow-overlap
data-layout-allow-occlusion
>
OMG IT&#39;S HTML
</div>
</div>
</div>
<div
class="item recv"
@@ -642,7 +686,16 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-recv"><div class="emojirow">🤯🤯🤯</div></div>
<div class="pop pop-recv">
<div
class="emojirow"
id="mtr-message-emoji"
data-layout-allow-overlap
data-layout-allow-occlusion
>
🤯🤯🤯
</div>
</div>
</div>
<div
class="item sent"
@@ -652,7 +705,14 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-occlusion
>
<div class="pop pop-sent">
<div class="bubble sent tail-sent">renders in 4K. no editor</div>
<div
class="bubble sent tail-sent"
id="mtr-message-benefit"
data-layout-allow-overlap
data-layout-allow-occlusion
>
renders in 4K. no editor
</div>
<div class="delivered">Delivered</div>
</div>
</div>
@@ -681,7 +741,14 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-occlusion
>
<div class="pop pop-recv">
<div class="bubble recv tail-recv">where did u find this</div>
<div
class="bubble recv tail-recv"
id="mtr-message-discovery"
data-layout-allow-overlap
data-layout-allow-occlusion
>
where did u find this
</div>
</div>
</div>
<div
@@ -691,7 +758,16 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-sent"><div class="bubble sent">on heygen</div></div>
<div class="pop pop-sent">
<div
class="bubble sent"
id="mtr-message-source"
data-layout-allow-overlap
data-layout-allow-occlusion
>
on heygen
</div>
</div>
</div>
<div
class="item sent"
@@ -701,7 +777,14 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-occlusion
>
<div class="pop pop-sent">
<div class="bubble sent">u just write plain html tags</div>
<div
class="bubble sent"
id="mtr-message-workflow"
data-layout-allow-overlap
data-layout-allow-occlusion
>
u just write plain html tags
</div>
</div>
</div>
<div
@@ -712,7 +795,14 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-occlusion
>
<div class="pop pop-sent">
<div class="bubble sent tail-sent">the code is yours forever</div>
<div
class="bubble sent tail-sent"
id="mtr-message-ownership"
data-layout-allow-overlap
data-layout-allow-occlusion
>
the code is yours forever
</div>
<div class="delivered">Delivered</div>
</div>
</div>
@@ -723,7 +813,16 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-recv"><div class="bubble recv">installing rn</div></div>
<div class="pop pop-recv">
<div
class="bubble recv"
id="mtr-message-install"
data-layout-allow-overlap
data-layout-allow-occlusion
>
installing rn
</div>
</div>
</div>
<div
class="item recv"
@@ -732,7 +831,16 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-recv"><div class="bubble recv tail-recv">ty bestie 💚</div></div>
<div class="pop pop-recv">
<div
class="bubble recv tail-recv"
id="mtr-message-thanks"
data-layout-allow-overlap
data-layout-allow-occlusion
>
ty bestie 💚
</div>
</div>
</div>
</div>
<div id="mtr-plusbtn">+</div>
@@ -924,7 +1032,12 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
style="z-index: 5"
>
<div id="mtr-ec-wrap" data-layout-allow-overlap data-layout-allow-occlusion>
<img id="mtr-ec-logo" src="assets/hyperframes-logo-black.svg" alt="HyperFrames" />
<img
id="mtr-ec-logo"
data-var-src="brandLogo"
src="assets/hyperframes-logo-black.svg"
alt="Brand logo"
/>
<div id="mtr-ec-stars">
<svg width="55" height="53" viewBox="0 0 24 23">
<path
@@ -982,15 +1095,15 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
/>
</svg>
</div>
<div class="ec-label" style="left: 100px">
<div class="ec-label" id="mtr-ec-feature-1" style="left: 100px">
<div>Write</div>
<div>plain HTML</div>
</div>
<div class="ec-label" style="left: 420px">
<div class="ec-label" id="mtr-ec-feature-2" style="left: 420px">
<div>Render</div>
<div>pixel-perfect</div>
</div>
<div class="ec-label" style="left: 740px">
<div class="ec-label" id="mtr-ec-feature-3" style="left: 740px">
<div>Own</div>
<div>every line</div>
</div>
@@ -1021,6 +1134,58 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
chev.className = "chev";
chev.textContent = "\u203A";
namePill.appendChild(chev);
function setText(id, value) {
document.getElementById(id).textContent = value;
}
function setTyped(group, value) {
var frames = Array.from(document.querySelectorAll('[id^="mtr-ty-' + group + '-"]')).sort(
function (a, b) {
return Number(a.id.split("-").pop()) - Number(b.id.split("-").pop());
},
);
var characters = Array.from(value);
frames.forEach(function (frame, index) {
var prefixLength = Math.max(
1,
Math.ceil((characters.length * (index + 1)) / frames.length),
);
var textNode = Array.from(frame.childNodes).find(function (node) {
return node.nodeType === 3;
});
if (textNode) textNode.nodeValue = characters.slice(0, prefixLength).join("");
});
}
function setTwoLines(id, value) {
var lines = value.split("|").slice(0, 2);
var container = document.getElementById(id);
Array.from(container.children).forEach(function (line, index) {
line.textContent = lines[index] || lines[0] || "";
});
}
var teaserMessage = text(vars.teaserMessage, "wait look 👀", 20);
var benefitMessage = text(vars.benefitMessage, "renders in 4K. no editor", 32);
var sourceMessage = text(vars.sourceMessage, "on heygen", 20);
var workflowMessage = text(vars.workflowMessage, "u just write plain html tags", 34);
var ownershipMessage = text(vars.ownershipMessage, "the code is yours forever", 32);
setText(
"mtr-message-question",
text(vars.questionMessage, "what r u using for the launch video??", 46),
);
setText("mtr-message-teaser", teaserMessage);
setText("mtr-message-reaction", text(vars.reactionMessage, "OMG IT'S HTML", 24));
setText("mtr-message-emoji", text(vars.reactionEmoji, "🤯🤯🤯", 12));
setText("mtr-message-benefit", benefitMessage);
setText("mtr-message-discovery", text(vars.discoveryMessage, "where did u find this", 28));
setText("mtr-message-source", sourceMessage);
setText("mtr-message-workflow", workflowMessage);
setText("mtr-message-ownership", ownershipMessage);
setText("mtr-message-install", text(vars.installMessage, "installing rn", 20));
setText("mtr-message-thanks", text(vars.thanksMessage, "ty bestie 💚", 20));
setTyped(1, teaserMessage);
setTyped(2, benefitMessage);
setTyped(3, sourceMessage);
setTyped(4, workflowMessage);
setTyped(5, ownershipMessage);
document.querySelector(".cardtitle").textContent = text(
vars.cardTitle,
"HyperFrames | Write HTML, render pixel-perfect video",
@@ -1036,6 +1201,9 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
"12,000+ creators",
30,
);
setTwoLines("mtr-ec-feature-1", text(vars.ecFeature1, "Write|plain HTML", 32));
setTwoLines("mtr-ec-feature-2", text(vars.ecFeature2, "Render|pixel-perfect", 32));
setTwoLines("mtr-ec-feature-3", text(vars.ecFeature3, "Own|every line", 32));
document.getElementById("mtr-ec-cta").textContent = text(
vars.ecCta,
"Start rendering free",
@@ -1477,7 +1645,7 @@ import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
<InstallCommand command="npx hyperframes add message-thread-reveal" item="message-thread-reveal" />
That writes `compositions/message-thread-reveal.html`, plus 2 supporting files under `assets/`.
That writes `compositions/message-thread-reveal.html`, plus 3 supporting files under `assets/`.
## Add it to your video
@@ -1506,9 +1674,25 @@ want to change on the element:
| Variable | Default | Accepts | What it does |
| --- | --- | --- | --- |
| `contactName` | `Rachel` | string | Name pill in the chat header; the avatar shows its first letter. |
| `questionMessage` | `what r u using for the launch video??` | string | First incoming message that establishes what the conversation is about. |
| `teaserMessage` | `wait look 👀` | string | First typed outgoing reply before the shared link card. |
| `cardImage` | `assets/card-image.jpg` | image | Preview image on the shared link card. |
| `cardTitle` | `HyperFrames | Write HTML, render pixel-perfect video` | string | Title on the shared link card. |
| `cardDomain` | `hyperframes.heygen.com` | string | Domain line under the card title. |
| `reactionMessage` | `OMG IT'S HTML` | string | Incoming reaction immediately after the shared link. |
| `reactionEmoji` | `🤯🤯🤯` | string | Emoji-only reaction after the shared link. |
| `benefitMessage` | `renders in 4K. no editor` | string | Typed outgoing reply that names the primary benefit. |
| `discoveryMessage` | `where did u find this` | string | Incoming question asking where the product was found. |
| `sourceMessage` | `on heygen` | string | Typed outgoing reply naming where to find the product. |
| `workflowMessage` | `u just write plain html tags` | string | Typed outgoing reply describing how the product works. |
| `ownershipMessage` | `the code is yours forever` | string | Typed outgoing reply that closes the product explanation. |
| `installMessage` | `installing rn` | string | Incoming message expressing intent to try the product. |
| `thanksMessage` | `ty bestie 💚` | string | Final incoming message in the conversation. |
| `brandLogo` | `assets/hyperframes-logo-black.svg` | image | Transparent horizontal wordmark on the closing card. |
| `ecProof` | `12,000+ creators` | string | Social-proof line under the stars. |
| `ecFeature1` | `Write|plain HTML` | string | First two-line benefit; use | to break the line. |
| `ecFeature2` | `Render|pixel-perfect` | string | Second two-line benefit; use | to break the line. |
| `ecFeature3` | `Own|every line` | string | Third two-line benefit; use | to break the line. |
| `ecCta` | `Start rendering free` | string | Label on the closing card button. |
Set them with `data-variable-values` on the element that mounts it. These are the
@@ -1518,7 +1702,7 @@ defaults, so this behaves exactly like the preview above until you change one:
<div
data-composition-id="message-thread-reveal"
data-composition-src="compositions/message-thread-reveal.html"
data-variable-values='{"contactName":"Rachel","cardTitle":"HyperFrames | Write HTML, render pixel-perfect video","cardDomain":"hyperframes.heygen.com","ecProof":"12,000+ creators","ecCta":"Start rendering free"}'
data-variable-values='{"contactName":"Rachel","questionMessage":"what r u using for the launch video??","teaserMessage":"wait look 👀","cardImage":"assets/card-image.jpg","cardTitle":"HyperFrames | Write HTML, render pixel-perfect video","cardDomain":"hyperframes.heygen.com","reactionMessage":"OMG IT'S HTML","reactionEmoji":"🤯🤯🤯","benefitMessage":"renders in 4K. no editor","discoveryMessage":"where did u find this","sourceMessage":"on heygen","workflowMessage":"u just write plain html tags","ownershipMessage":"the code is yours forever","installMessage":"installing rn","thanksMessage":"ty bestie 💚","brandLogo":"assets/hyperframes-logo-black.svg","ecProof":"12,000+ creators","ecFeature1":"Write|plain HTML","ecFeature2":"Render|pixel-perfect","ecFeature3":"Own|every line","ecCta":"Start rendering free"}'
></div>
```
@@ -1532,9 +1716,25 @@ defaults, so this behaves exactly like the preview above until you change one:
lang="en"
data-composition-variables='[
{ "id": "contactName", "type": "string", "role": "content", "label": "Contact name", "description": "Name pill in the chat header; the avatar shows its first letter.", "default": "Rachel" },
{ "id": "questionMessage", "type": "string", "role": "content", "label": "Opening question", "description": "First incoming message that establishes what the conversation is about.", "default": "what r u using for the launch video??" },
{ "id": "teaserMessage", "type": "string", "role": "content", "label": "Teaser reply", "description": "First typed outgoing reply before the shared link card.", "default": "wait look 👀" },
{ "id": "cardImage", "type": "image", "role": "content", "label": "Link card image", "description": "Preview image on the shared link card.", "default": "assets/card-image.jpg" },
{ "id": "cardTitle", "type": "string", "role": "content", "label": "Link card title", "description": "Title on the shared link card.", "default": "HyperFrames | Write HTML, render pixel-perfect video" },
{ "id": "cardDomain", "type": "string", "role": "content", "label": "Link card domain", "description": "Domain line under the card title.", "default": "hyperframes.heygen.com" },
{ "id": "reactionMessage", "type": "string", "role": "content", "label": "Link reaction", "description": "Incoming reaction immediately after the shared link.", "default": "OMG IT&#39;S HTML" },
{ "id": "reactionEmoji", "type": "string", "role": "content", "label": "Reaction emoji", "description": "Emoji-only reaction after the shared link.", "default": "🤯🤯🤯" },
{ "id": "benefitMessage", "type": "string", "role": "content", "label": "Benefit reply", "description": "Typed outgoing reply that names the primary benefit.", "default": "renders in 4K. no editor" },
{ "id": "discoveryMessage", "type": "string", "role": "content", "label": "Discovery question", "description": "Incoming question asking where the product was found.", "default": "where did u find this" },
{ "id": "sourceMessage", "type": "string", "role": "content", "label": "Source reply", "description": "Typed outgoing reply naming where to find the product.", "default": "on heygen" },
{ "id": "workflowMessage", "type": "string", "role": "content", "label": "Workflow reply", "description": "Typed outgoing reply describing how the product works.", "default": "u just write plain html tags" },
{ "id": "ownershipMessage", "type": "string", "role": "content", "label": "Ownership reply", "description": "Typed outgoing reply that closes the product explanation.", "default": "the code is yours forever" },
{ "id": "installMessage", "type": "string", "role": "content", "label": "Intent reply", "description": "Incoming message expressing intent to try the product.", "default": "installing rn" },
{ "id": "thanksMessage", "type": "string", "role": "content", "label": "Closing reply", "description": "Final incoming message in the conversation.", "default": "ty bestie 💚" },
{ "id": "brandLogo", "type": "image", "role": "content", "label": "Brand logo", "description": "Transparent horizontal wordmark on the closing card.", "default": "assets/hyperframes-logo-black.svg" },
{ "id": "ecProof", "type": "string", "role": "content", "label": "End-card proof", "description": "Social-proof line under the stars.", "default": "12,000+ creators" },
{ "id": "ecFeature1", "type": "string", "role": "content", "label": "End-card feature 1", "description": "First two-line benefit; use | to break the line.", "default": "Write|plain HTML" },
{ "id": "ecFeature2", "type": "string", "role": "content", "label": "End-card feature 2", "description": "Second two-line benefit; use | to break the line.", "default": "Render|pixel-perfect" },
{ "id": "ecFeature3", "type": "string", "role": "content", "label": "End-card feature 3", "description": "Third two-line benefit; use | to break the line.", "default": "Own|every line" },
{ "id": "ecCta", "type": "string", "role": "content", "label": "End-card CTA", "description": "Label on the closing card button.", "default": "Start rendering free" }
]'
>
@@ -2085,7 +2285,14 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-occlusion
>
<div class="pop pop-recv">
<div class="bubble recv">what r u using for the launch video??</div>
<div
class="bubble recv"
id="mtr-message-question"
data-layout-allow-overlap
data-layout-allow-occlusion
>
what r u using for the launch video??
</div>
</div>
</div>
<div
@@ -2113,7 +2320,14 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-occlusion
>
<div class="pop pop-sent">
<div class="bubble sent tail-sent">wait look 👀</div>
<div
class="bubble sent tail-sent"
id="mtr-message-teaser"
data-layout-allow-overlap
data-layout-allow-occlusion
>
wait look 👀
</div>
<div class="delivered">Delivered</div>
</div>
</div>
@@ -2126,7 +2340,12 @@ defaults, so this behaves exactly like the preview above until you change one:
>
<div class="pop pop-sent">
<div class="card">
<img class="cardimg" src="assets/card-image.jpg" alt="" />
<img
class="cardimg"
data-var-src="cardImage"
src="assets/card-image.jpg"
alt=""
/>
<div class="cardmeta">
<div class="cardtxt">
<div class="cardtitle">
@@ -2146,7 +2365,16 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-recv"><div class="bubble recv">OMG IT&#39;S HTML</div></div>
<div class="pop pop-recv">
<div
class="bubble recv"
id="mtr-message-reaction"
data-layout-allow-overlap
data-layout-allow-occlusion
>
OMG IT&#39;S HTML
</div>
</div>
</div>
<div
class="item recv"
@@ -2155,7 +2383,16 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-recv"><div class="emojirow">🤯🤯🤯</div></div>
<div class="pop pop-recv">
<div
class="emojirow"
id="mtr-message-emoji"
data-layout-allow-overlap
data-layout-allow-occlusion
>
🤯🤯🤯
</div>
</div>
</div>
<div
class="item sent"
@@ -2165,7 +2402,14 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-occlusion
>
<div class="pop pop-sent">
<div class="bubble sent tail-sent">renders in 4K. no editor</div>
<div
class="bubble sent tail-sent"
id="mtr-message-benefit"
data-layout-allow-overlap
data-layout-allow-occlusion
>
renders in 4K. no editor
</div>
<div class="delivered">Delivered</div>
</div>
</div>
@@ -2194,7 +2438,14 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-occlusion
>
<div class="pop pop-recv">
<div class="bubble recv tail-recv">where did u find this</div>
<div
class="bubble recv tail-recv"
id="mtr-message-discovery"
data-layout-allow-overlap
data-layout-allow-occlusion
>
where did u find this
</div>
</div>
</div>
<div
@@ -2204,7 +2455,16 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-sent"><div class="bubble sent">on heygen</div></div>
<div class="pop pop-sent">
<div
class="bubble sent"
id="mtr-message-source"
data-layout-allow-overlap
data-layout-allow-occlusion
>
on heygen
</div>
</div>
</div>
<div
class="item sent"
@@ -2214,7 +2474,14 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-occlusion
>
<div class="pop pop-sent">
<div class="bubble sent">u just write plain html tags</div>
<div
class="bubble sent"
id="mtr-message-workflow"
data-layout-allow-overlap
data-layout-allow-occlusion
>
u just write plain html tags
</div>
</div>
</div>
<div
@@ -2225,7 +2492,14 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-occlusion
>
<div class="pop pop-sent">
<div class="bubble sent tail-sent">the code is yours forever</div>
<div
class="bubble sent tail-sent"
id="mtr-message-ownership"
data-layout-allow-overlap
data-layout-allow-occlusion
>
the code is yours forever
</div>
<div class="delivered">Delivered</div>
</div>
</div>
@@ -2236,7 +2510,16 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-recv"><div class="bubble recv">installing rn</div></div>
<div class="pop pop-recv">
<div
class="bubble recv"
id="mtr-message-install"
data-layout-allow-overlap
data-layout-allow-occlusion
>
installing rn
</div>
</div>
</div>
<div
class="item recv"
@@ -2245,7 +2528,16 @@ defaults, so this behaves exactly like the preview above until you change one:
data-layout-allow-overlap
data-layout-allow-occlusion
>
<div class="pop pop-recv"><div class="bubble recv tail-recv">ty bestie 💚</div></div>
<div class="pop pop-recv">
<div
class="bubble recv tail-recv"
id="mtr-message-thanks"
data-layout-allow-overlap
data-layout-allow-occlusion
>
ty bestie 💚
</div>
</div>
</div>
</div>
<div id="mtr-plusbtn">+</div>
@@ -2437,7 +2729,12 @@ defaults, so this behaves exactly like the preview above until you change one:
style="z-index: 5"
>
<div id="mtr-ec-wrap" data-layout-allow-overlap data-layout-allow-occlusion>
<img id="mtr-ec-logo" src="assets/hyperframes-logo-black.svg" alt="HyperFrames" />
<img
id="mtr-ec-logo"
data-var-src="brandLogo"
src="assets/hyperframes-logo-black.svg"
alt="Brand logo"
/>
<div id="mtr-ec-stars">
<svg width="55" height="53" viewBox="0 0 24 23">
<path
@@ -2495,15 +2792,15 @@ defaults, so this behaves exactly like the preview above until you change one:
/>
</svg>
</div>
<div class="ec-label" style="left: 100px">
<div class="ec-label" id="mtr-ec-feature-1" style="left: 100px">
<div>Write</div>
<div>plain HTML</div>
</div>
<div class="ec-label" style="left: 420px">
<div class="ec-label" id="mtr-ec-feature-2" style="left: 420px">
<div>Render</div>
<div>pixel-perfect</div>
</div>
<div class="ec-label" style="left: 740px">
<div class="ec-label" id="mtr-ec-feature-3" style="left: 740px">
<div>Own</div>
<div>every line</div>
</div>
@@ -2534,6 +2831,58 @@ defaults, so this behaves exactly like the preview above until you change one:
chev.className = "chev";
chev.textContent = "\u203A";
namePill.appendChild(chev);
function setText(id, value) {
document.getElementById(id).textContent = value;
}
function setTyped(group, value) {
var frames = Array.from(document.querySelectorAll('[id^="mtr-ty-' + group + '-"]')).sort(
function (a, b) {
return Number(a.id.split("-").pop()) - Number(b.id.split("-").pop());
},
);
var characters = Array.from(value);
frames.forEach(function (frame, index) {
var prefixLength = Math.max(
1,
Math.ceil((characters.length * (index + 1)) / frames.length),
);
var textNode = Array.from(frame.childNodes).find(function (node) {
return node.nodeType === 3;
});
if (textNode) textNode.nodeValue = characters.slice(0, prefixLength).join("");
});
}
function setTwoLines(id, value) {
var lines = value.split("|").slice(0, 2);
var container = document.getElementById(id);
Array.from(container.children).forEach(function (line, index) {
line.textContent = lines[index] || lines[0] || "";
});
}
var teaserMessage = text(vars.teaserMessage, "wait look 👀", 20);
var benefitMessage = text(vars.benefitMessage, "renders in 4K. no editor", 32);
var sourceMessage = text(vars.sourceMessage, "on heygen", 20);
var workflowMessage = text(vars.workflowMessage, "u just write plain html tags", 34);
var ownershipMessage = text(vars.ownershipMessage, "the code is yours forever", 32);
setText(
"mtr-message-question",
text(vars.questionMessage, "what r u using for the launch video??", 46),
);
setText("mtr-message-teaser", teaserMessage);
setText("mtr-message-reaction", text(vars.reactionMessage, "OMG IT'S HTML", 24));
setText("mtr-message-emoji", text(vars.reactionEmoji, "🤯🤯🤯", 12));
setText("mtr-message-benefit", benefitMessage);
setText("mtr-message-discovery", text(vars.discoveryMessage, "where did u find this", 28));
setText("mtr-message-source", sourceMessage);
setText("mtr-message-workflow", workflowMessage);
setText("mtr-message-ownership", ownershipMessage);
setText("mtr-message-install", text(vars.installMessage, "installing rn", 20));
setText("mtr-message-thanks", text(vars.thanksMessage, "ty bestie 💚", 20));
setTyped(1, teaserMessage);
setTyped(2, benefitMessage);
setTyped(3, sourceMessage);
setTyped(4, workflowMessage);
setTyped(5, ownershipMessage);
document.querySelector(".cardtitle").textContent = text(
vars.cardTitle,
"HyperFrames | Write HTML, render pixel-perfect video",
@@ -2549,6 +2898,9 @@ defaults, so this behaves exactly like the preview above until you change one:
"12,000+ creators",
30,
);
setTwoLines("mtr-ec-feature-1", text(vars.ecFeature1, "Write|plain HTML", 32));
setTwoLines("mtr-ec-feature-2", text(vars.ecFeature2, "Render|pixel-perfect", 32));
setTwoLines("mtr-ec-feature-3", text(vars.ecFeature3, "Own|every line", 32));
document.getElementById("mtr-ec-cta").textContent = text(
vars.ecCta,
"Start rendering free",