mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 07:19:52 +00:00
2121 lines
73 KiB
Plaintext
2121 lines
73 KiB
Plaintext
---
|
||
title: "AI Chat Reveal"
|
||
description: "A question is typed on a rising keyboard, sent, and answered by an AI that streams its reply word by word on a measured token rhythm - thinking dot, uneven bursts, bulleted list - before the app cuts to a branded closing card"
|
||
---
|
||
|
||
import { InstallCommand } from "/snippets/install-command.jsx";
|
||
import { VariablesExplorer } from "/snippets/variables-explorer.jsx";
|
||
|
||
<VariablesExplorer
|
||
previewSrc="/public/catalog/blocks/ai-chat-reveal.json"
|
||
compositionId="ai-chat-reveal"
|
||
compositionSrc="compositions/ai-chat-reveal.html"
|
||
variables={[{"id":"botName","type":"string","role":"content","label":"Assistant name","description":"Title in the chat header.","default":"Assistant"},{"id":"userMessage","type":"string","role":"content","label":"User message","description":"The question typed on the keyboard and sent. Around 40 characters keeps the measured pacing.","default":"How do I turn my HTML into real video?"},{"id":"answer1","type":"string","role":"content","label":"Answer paragraph 1","description":"First streamed paragraph.","default":"You do not need an editor. HyperFrames renders the HTML you already write into deterministic, pixel-perfect video."},{"id":"answer2","type":"string","role":"content","label":"Answer paragraph 2","description":"Short second beat.","default":"It is markup, not magic."},{"id":"answer3","type":"string","role":"content","label":"Answer paragraph 3","description":"Lead-in to the list.","default":"What you get out of the box:"},{"id":"bullet1","type":"string","role":"content","label":"Bullet 1","description":"First list item.","default":"A catalog of motion primitives you install and own"},{"id":"bullet2","type":"string","role":"content","label":"Bullet 2","description":"Second list item.","default":"GSAP timelines that seek to any frame"},{"id":"bullet3","type":"string","role":"content","label":"Bullet 3","description":"Third list item.","default":"4K renders from a single CLI command"},{"id":"ecHeadline","type":"string","role":"content","label":"End-card headline","description":"Closing card headline. A | breaks the line.","default":"It's not magic.|It's HTML."},{"id":"ecSub","type":"string","role":"content","label":"End-card subline","description":"Supporting sentence on the closing card.","default":"Open-source video rendering — write HTML, ship pixel-perfect video."},{"id":"ecCta","type":"string","role":"content","label":"End-card CTA","description":"Label on the closing card button.","default":"Try HyperFrames"},{"id":"ecFooter","type":"string","role":"content","label":"End-card footer","description":"Letter-spaced line at the very bottom.","default":"HYPERFRAMES.HEYGEN.COM"}]}
|
||
>
|
||
|
||
```html ai-chat-reveal.html
|
||
<!doctype html>
|
||
<html
|
||
lang="en"
|
||
data-composition-variables='[
|
||
{ "id": "botName", "type": "string", "role": "content", "label": "Assistant name", "description": "Title in the chat header.", "default": "Assistant" },
|
||
{ "id": "userMessage", "type": "string", "role": "content", "label": "User message", "description": "The question typed on the keyboard and sent. Around 40 characters keeps the measured pacing.", "default": "How do I turn my HTML into real video?" },
|
||
{ "id": "answer1", "type": "string", "role": "content", "label": "Answer paragraph 1", "description": "First streamed paragraph.", "default": "You do not need an editor. HyperFrames renders the HTML you already write into deterministic, pixel-perfect video." },
|
||
{ "id": "answer2", "type": "string", "role": "content", "label": "Answer paragraph 2", "description": "Short second beat.", "default": "It is markup, not magic." },
|
||
{ "id": "answer3", "type": "string", "role": "content", "label": "Answer paragraph 3", "description": "Lead-in to the list.", "default": "What you get out of the box:" },
|
||
{ "id": "bullet1", "type": "string", "role": "content", "label": "Bullet 1", "description": "First list item.", "default": "A catalog of motion primitives you install and own" },
|
||
{ "id": "bullet2", "type": "string", "role": "content", "label": "Bullet 2", "description": "Second list item.", "default": "GSAP timelines that seek to any frame" },
|
||
{ "id": "bullet3", "type": "string", "role": "content", "label": "Bullet 3", "description": "Third list item.", "default": "4K renders from a single CLI command" },
|
||
{ "id": "ecHeadline", "type": "string", "role": "content", "label": "End-card headline", "description": "Closing card headline. A | breaks the line.", "default": "It's not magic.|It's HTML." },
|
||
{ "id": "ecSub", "type": "string", "role": "content", "label": "End-card subline", "description": "Supporting sentence on the closing card.", "default": "Open-source video rendering — write HTML, ship pixel-perfect video." },
|
||
{ "id": "ecCta", "type": "string", "role": "content", "label": "End-card CTA", "description": "Label on the closing card button.", "default": "Try HyperFrames" },
|
||
{ "id": "ecFooter", "type": "string", "role": "content", "label": "End-card footer", "description": "Letter-spaced line at the very bottom.", "default": "HYPERFRAMES.HEYGEN.COM" }
|
||
]'
|
||
>
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=1080, height=1920" />
|
||
<title>AI Chat Reveal</title>
|
||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
html,
|
||
body {
|
||
width: 1080px;
|
||
height: 1920px;
|
||
overflow: hidden;
|
||
background: #000;
|
||
}
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
|
||
}
|
||
/* The measured 750x1624 device UI is scaled uniformly into a standard
|
||
1080x1920 portrait canvas so its keyboard geometry stays pixel-true. */
|
||
#acr-root {
|
||
position: relative;
|
||
width: 1080px;
|
||
height: 1920px;
|
||
overflow: hidden;
|
||
}
|
||
.clip {
|
||
position: absolute;
|
||
inset: 0;
|
||
overflow: hidden;
|
||
}
|
||
#acr-chat {
|
||
background: #fdfdfd;
|
||
}
|
||
.acr-stage {
|
||
position: absolute;
|
||
left: 96.6502px;
|
||
top: 0;
|
||
width: 750px;
|
||
height: 1624px;
|
||
transform: scale(1.18226601);
|
||
transform-origin: top left;
|
||
}
|
||
#acr-chat-bg {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: #fdfdfd;
|
||
}
|
||
|
||
/* status bar */
|
||
#acr-statusbar {
|
||
position: absolute;
|
||
top: 14px;
|
||
left: 0;
|
||
right: 0;
|
||
height: 44px;
|
||
}
|
||
#acr-clock {
|
||
position: absolute;
|
||
left: 39px;
|
||
top: 9px;
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
letter-spacing: 2.4px;
|
||
font-variant-numeric: tabular-nums;
|
||
color: #0d0d0d;
|
||
}
|
||
#acr-sicons {
|
||
position: absolute;
|
||
right: 26px;
|
||
top: 8px;
|
||
display: flex;
|
||
gap: 9px;
|
||
align-items: center;
|
||
}
|
||
|
||
/* header */
|
||
#acr-header {
|
||
position: absolute;
|
||
top: 64px;
|
||
left: 0;
|
||
right: 0;
|
||
height: 52px;
|
||
}
|
||
#acr-hleft {
|
||
position: absolute;
|
||
left: 28px;
|
||
top: 12px;
|
||
}
|
||
#acr-htitle {
|
||
position: absolute;
|
||
left: 0;
|
||
right: 48px;
|
||
text-align: center;
|
||
top: 13px;
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
color: #0d0d0d;
|
||
}
|
||
.acr-hicons {
|
||
position: absolute;
|
||
right: 28px;
|
||
top: 14px;
|
||
display: flex;
|
||
gap: 26px;
|
||
align-items: center;
|
||
}
|
||
#acr-hicons-b {
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
|
||
/* user bubble */
|
||
#acr-bubble {
|
||
position: absolute;
|
||
top: 129px;
|
||
right: 32px;
|
||
max-width: 544px;
|
||
background: #f3f3f3;
|
||
border-radius: 34px;
|
||
padding: 20px 30px;
|
||
font-size: 27px;
|
||
line-height: 38.6px;
|
||
color: #111;
|
||
letter-spacing: 1.25px;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
|
||
/* answer */
|
||
#acr-answer {
|
||
position: absolute;
|
||
top: 267px;
|
||
left: 33px;
|
||
width: 662px;
|
||
font-size: 27px;
|
||
line-height: 38.6px;
|
||
color: #141414;
|
||
letter-spacing: 1.25px;
|
||
}
|
||
#acr-answer .acr-ap {
|
||
margin: 0 0 15.5px 0;
|
||
}
|
||
#acr-answer .acr-ali {
|
||
display: flex;
|
||
margin: 0 0 6.5px 0;
|
||
}
|
||
#acr-answer .acr-mark {
|
||
width: 30px;
|
||
flex: 0 0 30px;
|
||
text-align: center;
|
||
font-size: 18px;
|
||
line-height: 38.6px;
|
||
}
|
||
#acr-answer .acr-alitext {
|
||
flex: 1;
|
||
}
|
||
.acr-w {
|
||
opacity: 0;
|
||
}
|
||
#acr-dot {
|
||
position: absolute;
|
||
left: 32px;
|
||
top: 279px;
|
||
width: 15px;
|
||
height: 15px;
|
||
border-radius: 50%;
|
||
background: #646464;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
|
||
/* composer (rest dock; rides keyboard via transform) */
|
||
#acr-composer {
|
||
position: absolute;
|
||
left: 30px;
|
||
right: 30px;
|
||
bottom: 31px;
|
||
}
|
||
#acr-pill {
|
||
position: relative;
|
||
width: 100%;
|
||
min-height: 81px;
|
||
background: #fff;
|
||
border: 2px solid #ececec;
|
||
border-radius: 41px;
|
||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 13px 160px 13px 78px;
|
||
}
|
||
#acr-plusi {
|
||
position: absolute;
|
||
left: 30px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
#acr-ph {
|
||
position: absolute;
|
||
left: 78px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
color: #767676;
|
||
font-size: 28px;
|
||
letter-spacing: 1.25px;
|
||
}
|
||
#acr-ctextwrap {
|
||
width: 100%;
|
||
min-height: 38px;
|
||
}
|
||
#acr-ctext {
|
||
font-size: 29px;
|
||
line-height: 38px;
|
||
color: #0d0d0d;
|
||
letter-spacing: 1.25px;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
#acr-caret {
|
||
display: inline-block;
|
||
width: 3px;
|
||
height: 30px;
|
||
margin-left: 2px;
|
||
border-radius: 1.5px;
|
||
background: #0d0d0d;
|
||
vertical-align: -4px;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
#acr-cmic {
|
||
position: absolute;
|
||
right: 80px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
.acr-cbtn {
|
||
position: absolute;
|
||
right: 14px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 52px;
|
||
height: 52px;
|
||
border-radius: 50%;
|
||
display: grid;
|
||
place-items: center;
|
||
}
|
||
#acr-btn-send-grey {
|
||
background: #ececec;
|
||
}
|
||
#acr-btn-send-black {
|
||
background: #0d0d0d;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
#acr-btn-stop {
|
||
background: #0d0d0d;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
#acr-btn-stop .acr-sq {
|
||
width: 19px;
|
||
height: 19px;
|
||
border-radius: 5px;
|
||
background: #fff;
|
||
}
|
||
|
||
/* keyboard: geometry and #d2d5e0 ground measured from the reference */
|
||
#acr-keyboard {
|
||
position: absolute;
|
||
left: 0;
|
||
bottom: 0;
|
||
width: 750px;
|
||
height: 482px;
|
||
background: #d2d5e0;
|
||
}
|
||
#acr-suggest {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 74px;
|
||
display: flex;
|
||
}
|
||
#acr-suggest .acr-sug {
|
||
flex: 1;
|
||
display: grid;
|
||
place-items: center;
|
||
font-size: 29px;
|
||
color: #0d0d0d;
|
||
position: relative;
|
||
}
|
||
#acr-suggest .acr-sug + .acr-sug::before {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 16px;
|
||
bottom: 16px;
|
||
width: 1.5px;
|
||
background: #bcbabf;
|
||
}
|
||
.acr-key {
|
||
position: absolute;
|
||
height: 74px;
|
||
background: #fdfdfd;
|
||
border-radius: 10px;
|
||
box-shadow: 0 2px 0 #8b8a8f;
|
||
display: grid;
|
||
place-items: center;
|
||
font-size: 32px;
|
||
color: #000;
|
||
}
|
||
.acr-gkey {
|
||
background: #aeacaf;
|
||
}
|
||
.acr-num,
|
||
.acr-spc {
|
||
font-size: 27px;
|
||
}
|
||
.acr-kbstrip {
|
||
position: absolute;
|
||
bottom: 10px;
|
||
left: 0;
|
||
right: 0;
|
||
height: 52px;
|
||
}
|
||
.acr-kglobe {
|
||
position: absolute;
|
||
left: 48px;
|
||
top: 21px;
|
||
}
|
||
.acr-kmic {
|
||
position: absolute;
|
||
right: 52px;
|
||
top: 23px;
|
||
}
|
||
|
||
/* end card: the HyperFrames closing card, on the family's dark ground */
|
||
#acr-endcard-inner {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: linear-gradient(180deg, #14110e 0%, #221b13 100%);
|
||
opacity: 0;
|
||
}
|
||
#acr-eclogo {
|
||
position: absolute;
|
||
left: 255px;
|
||
top: 112px;
|
||
width: 240px;
|
||
height: 72px;
|
||
}
|
||
#acr-ecstar {
|
||
position: absolute;
|
||
left: 610px;
|
||
top: 230px;
|
||
}
|
||
#acr-ecvideo {
|
||
position: absolute;
|
||
left: 222px;
|
||
top: 336px;
|
||
width: 283px;
|
||
height: 454px;
|
||
border-radius: 36px;
|
||
background: linear-gradient(165deg, #0f3a2c 0%, #0a9c6b 78%, #3ce6ac 100%);
|
||
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
|
||
}
|
||
#acr-ecvideo .acr-play {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 108px;
|
||
height: 108px;
|
||
border-radius: 50%;
|
||
background: rgba(253, 253, 253, 0.94);
|
||
display: grid;
|
||
place-items: center;
|
||
}
|
||
#acr-echead {
|
||
position: absolute;
|
||
top: 946px;
|
||
left: 0;
|
||
right: 0;
|
||
text-align: center;
|
||
font-weight: 700;
|
||
font-size: 57px;
|
||
line-height: 58px;
|
||
color: #f7ece5;
|
||
letter-spacing: 0.5px;
|
||
}
|
||
#acr-ecsub {
|
||
position: absolute;
|
||
top: 1084px;
|
||
left: 65px;
|
||
right: 65px;
|
||
text-align: center;
|
||
font-weight: 500;
|
||
font-size: 31px;
|
||
line-height: 40px;
|
||
color: #cfc4b8;
|
||
}
|
||
#acr-eccta {
|
||
position: absolute;
|
||
left: 160px;
|
||
top: 1406px;
|
||
width: 429px;
|
||
height: 87px;
|
||
background: #3ce6ac;
|
||
border-radius: 44px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 22px;
|
||
}
|
||
#acr-eccta .acr-lbl {
|
||
color: #0d0d0d;
|
||
font-weight: 700;
|
||
font-size: 33px;
|
||
letter-spacing: 0.3px;
|
||
}
|
||
#acr-ecfoot {
|
||
position: absolute;
|
||
top: 1536px;
|
||
left: 0;
|
||
right: 0;
|
||
text-align: center;
|
||
font-weight: 700;
|
||
font-size: 25px;
|
||
letter-spacing: 4px;
|
||
color: #3ce6ac;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div
|
||
id="acr-root"
|
||
data-composition-id="ai-chat-reveal"
|
||
data-start="0"
|
||
data-width="1080"
|
||
data-height="1920"
|
||
data-duration="19.3333"
|
||
>
|
||
<section id="acr-chat" class="clip" data-start="0" data-duration="16.9" data-track-index="1">
|
||
<div class="acr-stage">
|
||
<div id="acr-chat-bg"></div>
|
||
|
||
<div id="acr-statusbar">
|
||
<div id="acr-clock">11:42</div>
|
||
<div id="acr-sicons">
|
||
<svg width="30" height="20" viewBox="0 0 20 12" fill="#0d0d0d">
|
||
<rect x="0" y="7" width="3" height="4" rx="1" />
|
||
<rect x="5" y="5" width="3" height="6" rx="1" />
|
||
<rect x="10" y="2.6" width="3" height="8.4" rx="1" />
|
||
<rect x="15" y="0.5" width="3" height="10.5" rx="1" /></svg
|
||
><svg
|
||
width="30"
|
||
height="21"
|
||
viewBox="0 0 22 15"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="2.2"
|
||
stroke-linecap="round"
|
||
>
|
||
<path d="M2 5 C7 -0.5 15 -0.5 20 5" fill="none" />
|
||
<path d="M5.5 8.6 C9 5 13 5 16.5 8.6" />
|
||
<path d="M9.2 12 C10.4 11 11.6 11 12.8 12" /></svg
|
||
><svg width="46" height="22" viewBox="0 0 30 14" fill="none">
|
||
<rect
|
||
x="0.8"
|
||
y="0.8"
|
||
width="25"
|
||
height="12.4"
|
||
rx="3.6"
|
||
stroke="#0d0d0d"
|
||
stroke-opacity="0.32"
|
||
stroke-width="1.2"
|
||
/>
|
||
<rect x="2.4" y="2.4" width="22.4" height="9.2" rx="2.4" fill="#0d0d0d" />
|
||
<path d="M28 4.6 v4.8 a2.4 2.4 0 0 0 0 -4.8" fill="#0d0d0d" fill-opacity="0.45" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="acr-header">
|
||
<div id="acr-hleft">
|
||
<svg
|
||
width="29"
|
||
height="29"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.9"
|
||
stroke-linecap="round"
|
||
>
|
||
<path d="M4 8 H20 M4 15 H12" />
|
||
</svg>
|
||
</div>
|
||
<div id="acr-htitle">Assistant</div>
|
||
<div class="acr-hicons" id="acr-hicons-a">
|
||
<svg
|
||
width="28"
|
||
height="28"
|
||
viewBox="0 0 26 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.7"
|
||
stroke-linecap="round"
|
||
>
|
||
<circle cx="10" cy="8" r="4" />
|
||
<path d="M3 21 C3 16 6.5 14 10 14 C13.5 14 17 16 17 21" />
|
||
<path d="M20 6 V12 M17 9 H23" /></svg
|
||
><svg
|
||
width="26"
|
||
height="26"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.7"
|
||
stroke-linecap="round"
|
||
stroke-dasharray="2.4 3.4"
|
||
>
|
||
<circle cx="12" cy="12" r="9" />
|
||
</svg>
|
||
</div>
|
||
<div class="acr-hicons" id="acr-hicons-b">
|
||
<svg
|
||
width="23"
|
||
height="23"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.7"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<path
|
||
d="M4 20 L5 15.5 L16.5 4 C17.6 2.9 19.4 2.9 20.5 4 C21.6 5.1 21.6 6.9 20.5 8 L9 19.5 L4 20 Z"
|
||
/></svg
|
||
><svg width="34" height="34" viewBox="0 0 24 24" fill="#0d0d0d">
|
||
<circle cx="5" cy="12" r="1.7" />
|
||
<circle cx="12" cy="12" r="1.7" />
|
||
<circle cx="19" cy="12" r="1.7" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="acr-bubble">How do I turn my HTML into real video?</div>
|
||
|
||
<div id="acr-dot"></div>
|
||
<div id="acr-answer" data-layout-allow-occlusion></div>
|
||
|
||
<div id="acr-composer">
|
||
<div id="acr-pill">
|
||
<div id="acr-plusi">
|
||
<svg
|
||
width="22"
|
||
height="22"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.9"
|
||
stroke-linecap="round"
|
||
>
|
||
<path d="M12 5 V19 M5 12 H19" />
|
||
</svg>
|
||
</div>
|
||
<div id="acr-ph" data-layout-allow-overlap data-layout-allow-occlusion>
|
||
Ask anything
|
||
</div>
|
||
<div id="acr-ctextwrap"><span id="acr-ctext"></span><span id="acr-caret"></span></div>
|
||
<div id="acr-cmic">
|
||
<svg
|
||
width="15"
|
||
height="22"
|
||
viewBox="0 0 24 34"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
>
|
||
<rect x="8" y="2" width="8" height="16" rx="4" fill="#0d0d0d" stroke="none" />
|
||
<path d="M4 14 a8 8 0 0 0 16 0 M12 22 V28 M7 31 H17" stroke-width="2.2" />
|
||
</svg>
|
||
</div>
|
||
<div class="acr-cbtn" id="acr-btn-send-grey">
|
||
<svg
|
||
width="26"
|
||
height="26"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#b6b6b6"
|
||
stroke-width="2.6"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<path d="M12 19 V6 M6.5 11 L12 5.5 L17.5 11" />
|
||
</svg>
|
||
</div>
|
||
<div class="acr-cbtn" id="acr-btn-send-black">
|
||
<svg
|
||
width="26"
|
||
height="26"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#fff"
|
||
stroke-width="2.6"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<path d="M12 19 V6 M6.5 11 L12 5.5 L17.5 11" />
|
||
</svg>
|
||
</div>
|
||
<div class="acr-cbtn" id="acr-btn-stop"><div class="acr-sq"></div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="acr-keyboard">
|
||
<div id="acr-suggest">
|
||
<div class="acr-sug">How</div>
|
||
<div class="acr-sug">Can</div>
|
||
<div class="acr-sug">My</div>
|
||
</div>
|
||
<div id="acr-keys"></div>
|
||
<div class="acr-kbstrip">
|
||
<span class="acr-kglobe"
|
||
><svg
|
||
width="30"
|
||
height="30"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#000"
|
||
stroke-width="2.6"
|
||
>
|
||
<circle cx="12" cy="12" r="9.6" />
|
||
<path
|
||
d="M2.4 12 H21.6 M12 2.4 C7.8 6.8 7.8 17.2 12 21.6 C16.2 17.2 16.2 6.8 12 2.4 M4 7 H20 M4 17 H20"
|
||
stroke-width="2.2"
|
||
/></svg></span
|
||
><span class="acr-kmic"
|
||
><svg
|
||
width="16"
|
||
height="25"
|
||
viewBox="0 0 24 34"
|
||
preserveAspectRatio="none"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="3.9"
|
||
stroke-linecap="round"
|
||
>
|
||
<rect
|
||
x="5.5"
|
||
y="1"
|
||
width="13"
|
||
height="17.5"
|
||
rx="6.5"
|
||
fill="#0d0d0d"
|
||
stroke="none"
|
||
/>
|
||
<path d="M2.5 14 a9.5 9.5 0 0 0 19 0 M12 23.5 V28.5 M5.5 32 H18.5" /></svg
|
||
></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section
|
||
id="acr-endcard"
|
||
class="clip"
|
||
data-start="15.8"
|
||
data-duration="3.5333"
|
||
data-track-index="2"
|
||
>
|
||
<div id="acr-endcard-inner">
|
||
<div class="acr-stage">
|
||
<img id="acr-eclogo" src="assets/hyperframes-logo-white.svg" alt="HyperFrames" />
|
||
<svg id="acr-ecstar" width="80" height="80" viewBox="0 0 80 80">
|
||
<g stroke="#2f6b57" stroke-width="8.5" stroke-linecap="round">
|
||
<line x1="47" y1="40" x2="77" y2="40" />
|
||
<line x1="46.5" y1="42.7" x2="74.2" y2="54.2" />
|
||
<line x1="44.9" y1="44.9" x2="66.2" y2="66.2" />
|
||
<line x1="42.7" y1="46.5" x2="54.2" y2="74.2" />
|
||
<line x1="40" y1="47" x2="40" y2="77" />
|
||
<line x1="37.3" y1="46.5" x2="25.8" y2="74.2" />
|
||
<line x1="35.1" y1="44.9" x2="13.8" y2="66.2" />
|
||
<line x1="33.5" y1="42.7" x2="5.8" y2="54.2" />
|
||
<line x1="33" y1="40" x2="3" y2="40" />
|
||
<line x1="33.5" y1="37.3" x2="5.8" y2="25.8" />
|
||
<line x1="35.1" y1="35.1" x2="13.8" y2="13.8" />
|
||
<line x1="37.3" y1="33.5" x2="25.8" y2="5.8" />
|
||
<line x1="40" y1="33" x2="40" y2="3" />
|
||
<line x1="42.7" y1="33.5" x2="54.2" y2="5.8" />
|
||
<line x1="44.9" y1="35.1" x2="66.2" y2="13.8" />
|
||
<line x1="46.5" y1="37.3" x2="74.2" y2="25.8" />
|
||
</g>
|
||
</svg>
|
||
<div id="acr-ecvideo">
|
||
<div class="acr-play">
|
||
<svg width="40" height="46" viewBox="0 0 44 48" fill="none">
|
||
<path
|
||
d="M40.5 20.6 C43.2 22.1 43.2 25.9 40.5 27.4 L6.2 46.6 C3.5 48.1 0.2 46.2 0.2 43.2 L0.2 4.8 C0.2 1.8 3.5 -0.1 6.2 1.4 Z"
|
||
fill="#0d0d0d"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
<div id="acr-echead">It's not magic.<br />It's HTML.</div>
|
||
<div id="acr-ecsub">
|
||
Open-source video rendering — write HTML, ship pixel-perfect video.
|
||
</div>
|
||
<div id="acr-eccta">
|
||
<span class="acr-lbl">Try HyperFrames</span
|
||
><svg
|
||
width="30"
|
||
height="34"
|
||
viewBox="0 0 16 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="2.6"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<path d="M4 3 L13 12 L4 21" />
|
||
</svg>
|
||
</div>
|
||
<div id="acr-ecfoot">HYPERFRAMES.HEYGEN.COM</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<script>
|
||
(function () {
|
||
"use strict";
|
||
|
||
/* -------- variables -------- */
|
||
var vars =
|
||
window.__hyperframes && typeof window.__hyperframes.getVariables === "function"
|
||
? window.__hyperframes.getVariables()
|
||
: {};
|
||
|
||
function text(value, fallback, max) {
|
||
if (typeof value !== "string") return fallback;
|
||
var t = value.trim();
|
||
if (!t) return fallback;
|
||
return t.length > max ? t.slice(0, max) : t;
|
||
}
|
||
|
||
var botName = text(vars.botName, "Assistant", 24);
|
||
var userMessage = text(vars.userMessage, "How do I turn my HTML into real video?", 60);
|
||
var answer1 = text(
|
||
vars.answer1,
|
||
"You do not need an editor. HyperFrames renders the HTML you already write into deterministic, pixel-perfect video.",
|
||
220,
|
||
);
|
||
var answer2 = text(vars.answer2, "It is markup, not magic.", 120);
|
||
var answer3 = text(vars.answer3, "What you get out of the box:", 120);
|
||
var bullets = [
|
||
text(vars.bullet1, "A catalog of motion primitives you install and own", 90),
|
||
text(vars.bullet2, "GSAP timelines that seek to any frame", 90),
|
||
text(vars.bullet3, "4K renders from a single CLI command", 90),
|
||
];
|
||
|
||
document.getElementById("acr-htitle").textContent = botName;
|
||
document.getElementById("acr-bubble").textContent = userMessage;
|
||
document.getElementById("acr-echead").innerHTML = "";
|
||
text(vars.ecHeadline, "It's not magic.|It's HTML.", 60)
|
||
.split("|")
|
||
.forEach(function (line, i) {
|
||
var head = document.getElementById("acr-echead");
|
||
if (i > 0) head.appendChild(document.createElement("br"));
|
||
head.appendChild(document.createTextNode(line));
|
||
});
|
||
document.getElementById("acr-ecsub").textContent = text(
|
||
vars.ecSub,
|
||
"Open-source video rendering — write HTML, ship pixel-perfect video.",
|
||
140,
|
||
);
|
||
document.querySelector("#acr-eccta .acr-lbl").textContent = text(
|
||
vars.ecCta,
|
||
"Try HyperFrames",
|
||
30,
|
||
);
|
||
document.getElementById("acr-ecfoot").textContent = text(
|
||
vars.ecFooter,
|
||
"HYPERFRAMES.HEYGEN.COM",
|
||
40,
|
||
);
|
||
|
||
/* -------- build the answer DOM: paragraphs of word spans, then bullets -------- */
|
||
var answerEl = document.getElementById("acr-answer");
|
||
var wordEls = [];
|
||
function addPara(str) {
|
||
var p = document.createElement("p");
|
||
p.className = "acr-ap";
|
||
str.split(/\s+/).forEach(function (word, i) {
|
||
if (i > 0) p.appendChild(document.createTextNode(" "));
|
||
var s = document.createElement("span");
|
||
s.className = "acr-w";
|
||
s.textContent = word;
|
||
p.appendChild(s);
|
||
wordEls.push(s);
|
||
});
|
||
answerEl.appendChild(p);
|
||
}
|
||
addPara(answer1);
|
||
addPara(answer2);
|
||
addPara(answer3);
|
||
bullets.forEach(function (b) {
|
||
var row = document.createElement("div");
|
||
row.className = "acr-ali";
|
||
var mark = document.createElement("span");
|
||
mark.className = "acr-mark acr-w";
|
||
mark.textContent = "•";
|
||
row.appendChild(mark);
|
||
wordEls.push(mark);
|
||
var body = document.createElement("div");
|
||
body.className = "acr-alitext";
|
||
b.split(/\s+/).forEach(function (word, i) {
|
||
if (i > 0) body.appendChild(document.createTextNode(" "));
|
||
var s = document.createElement("span");
|
||
s.className = "acr-w";
|
||
s.textContent = word;
|
||
body.appendChild(s);
|
||
wordEls.push(s);
|
||
});
|
||
row.appendChild(body);
|
||
answerEl.appendChild(row);
|
||
});
|
||
|
||
/* -------- build the keyboard: measured key geometry -------- */
|
||
var keysEl = document.getElementById("acr-keys");
|
||
var ROWS = [
|
||
{ top: 83, left: 13, letters: "qwertyuiop" },
|
||
{ top: 173, left: 48, letters: "asdfghjkl" },
|
||
{ top: 263, left: 123, letters: "zxcvbnm" },
|
||
];
|
||
ROWS.forEach(function (row) {
|
||
row.letters.split("").forEach(function (ch, i) {
|
||
var k = document.createElement("div");
|
||
k.className = "acr-key";
|
||
k.style.left = row.left + i * 73.7 + "px";
|
||
k.style.top = row.top + "px";
|
||
k.style.width = "62px";
|
||
k.textContent = ch;
|
||
keysEl.appendChild(k);
|
||
});
|
||
});
|
||
[
|
||
{
|
||
left: 13,
|
||
top: 263,
|
||
width: 97,
|
||
cls: " acr-gkey",
|
||
html: '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="1.6" stroke-linejoin="round"><path d="M12 4 L4.5 12 H8.5 V17 H15.5 V12 H19.5 Z"/></svg>',
|
||
},
|
||
{
|
||
left: 640,
|
||
top: 263,
|
||
width: 98,
|
||
cls: " acr-gkey",
|
||
html: '<svg width="31" height="24" viewBox="0 0 28 20" fill="none" stroke="#000" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"><path d="M9 2 H26 V18 H9 L1.5 10 Z"/><path d="M13 6.5 L20 13.5 M20 6.5 L13 13.5"/></svg>',
|
||
},
|
||
{ left: 13, top: 353, width: 97, cls: " acr-gkey acr-num", html: "123" },
|
||
{
|
||
left: 118,
|
||
top: 353,
|
||
width: 86,
|
||
cls: "",
|
||
html: '<svg width="27" height="27" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="1.4" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><circle cx="9" cy="10" r="0.6" fill="#000"/><circle cx="15" cy="10" r="0.6" fill="#000"/><path d="M8 14.5 C9.5 16.5 14.5 16.5 16 14.5"/></svg>',
|
||
},
|
||
{ left: 217, top: 353, width: 389, cls: " acr-spc", html: "space" },
|
||
{
|
||
left: 614,
|
||
top: 353,
|
||
width: 124,
|
||
cls: " acr-gkey",
|
||
html: '<svg width="27" height="27" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M19 5 V11 H6"/><path d="M9.5 7.5 L6 11 L9.5 14.5"/></svg>',
|
||
},
|
||
].forEach(function (spec) {
|
||
var k = document.createElement("div");
|
||
k.className = "acr-key" + spec.cls;
|
||
k.style.left = spec.left + "px";
|
||
k.style.top = spec.top + "px";
|
||
k.style.width = spec.width + "px";
|
||
k.innerHTML = spec.html;
|
||
keysEl.appendChild(k);
|
||
});
|
||
|
||
/* -------- timeline -------- */
|
||
window.__timelines = window.__timelines || {};
|
||
var tl = gsap.timeline({ paused: true });
|
||
|
||
/* keystroke and token rhythms, measured from the reference and cycled */
|
||
var KEY_GAPS = [
|
||
0.1, 0.033, 0.2, 0.133, 0.2, 0.033, 0.067, 0.033, 0.1, 0.067, 0.033, 0.067, 0.067, 0.067,
|
||
0.133, 0.067, 0.033, 0.067, 0.1, 0.1, 0.067, 0.133, 0.1, 0.033, 0.1, 0.033, 0.167, 0.033,
|
||
0.1, 0.1, 0.067, 0.133, 0.033, 0.067, 0.1, 0.033, 0.1, 0.067,
|
||
];
|
||
var WORD_GAPS = [
|
||
0.167, 0.1, 0.0, 0.367, 0.0, 0.167, 0.133, 0.1, 0.1, 0.133, 0.167, 0.133, 0.0, 0.233,
|
||
0.167, 0.1, 0.0, 0.133, 0.133, 0.1, 0.167, 0.133, 0.1, 0.133, 0.167, 0.1, 0.133, 0.1,
|
||
0.133,
|
||
];
|
||
|
||
/* keyboard rises, composer rides it (verbatim anchors) */
|
||
tl.fromTo("#acr-keyboard", { y: 482 }, { y: 0, duration: 0.2667, ease: "power2.out" }, 0.2);
|
||
tl.fromTo(
|
||
"#acr-composer",
|
||
{ y: 0 },
|
||
{ y: -497, duration: 0.2667, ease: "power2.out" },
|
||
0.2,
|
||
);
|
||
|
||
/* typing: two characters land on the first beat, then the measured gaps */
|
||
tl.set("#acr-ctext", { textContent: "", autoAlpha: 0 }, 0.001);
|
||
var TYPE_START = 0.8637;
|
||
tl.set("#acr-ctext", { autoAlpha: 1 }, TYPE_START);
|
||
tl.set("#acr-ph", { autoAlpha: 0 }, TYPE_START);
|
||
tl.set("#acr-btn-send-grey", { autoAlpha: 0 }, TYPE_START);
|
||
tl.set("#acr-btn-send-black", { autoAlpha: 1 }, TYPE_START);
|
||
var t = TYPE_START;
|
||
for (var n = 2; n <= userMessage.length; n += 1) {
|
||
tl.set("#acr-ctext", { textContent: userMessage.slice(0, n) }, t);
|
||
t += KEY_GAPS[(n - 2) % KEY_GAPS.length];
|
||
}
|
||
var typeEnd = t;
|
||
/* caret blinks on a steady half-second while typing */
|
||
tl.set("#acr-caret", { autoAlpha: 0 }, 0.001);
|
||
for (var c = TYPE_START, on = true; c < typeEnd; c += 0.5333, on = !on) {
|
||
tl.set("#acr-caret", { autoAlpha: on ? 1 : 0 }, c);
|
||
}
|
||
|
||
/* send: bubble pops, keyboard drops, stream begins */
|
||
var SEND = typeEnd + 0.1667;
|
||
tl.set("#acr-caret", { autoAlpha: 0 }, SEND);
|
||
tl.set("#acr-ctext", { textContent: "" }, SEND);
|
||
tl.set("#acr-ph", { autoAlpha: 1 }, SEND);
|
||
tl.set("#acr-btn-send-black", { autoAlpha: 0 }, SEND);
|
||
tl.set("#acr-btn-stop", { autoAlpha: 1 }, SEND);
|
||
tl.fromTo(
|
||
"#acr-bubble",
|
||
{ autoAlpha: 0 },
|
||
{ autoAlpha: 1, duration: 0.1667, ease: "power1.out" },
|
||
SEND - 0.03,
|
||
);
|
||
tl.set("#acr-hicons-a", { autoAlpha: 0 }, SEND);
|
||
tl.set("#acr-hicons-b", { autoAlpha: 1 }, SEND);
|
||
tl.to("#acr-keyboard", { y: 482, duration: 0.2667, ease: "power1.inOut" }, SEND - 0.03);
|
||
tl.to("#acr-composer", { y: 0, duration: 0.2667, ease: "power1.inOut" }, SEND - 0.03);
|
||
|
||
/* thinking dot: the measured alpha ramp, then it yields to the words */
|
||
var DOT_RAMP = [
|
||
0.488, 0.53, 0.53, 0.56, 0.608, 0.687, 0.729, 0.771, 0.813, 0.867, 0.904, 0.988, 1,
|
||
];
|
||
var dotStart = SEND + 0.4333;
|
||
tl.set("#acr-dot", { autoAlpha: 0 }, 0.001);
|
||
DOT_RAMP.forEach(function (a, i) {
|
||
tl.set("#acr-dot", { autoAlpha: a }, dotStart + i * 0.0333);
|
||
});
|
||
tl.set("#acr-dot", { autoAlpha: 0 }, dotStart + 0.5667);
|
||
|
||
/* the stream: measured token rhythm, fresh grey inking to full colour */
|
||
var w = dotStart + 0.6333;
|
||
wordEls.forEach(function (el, i) {
|
||
if (i > 0) w += WORD_GAPS[i % WORD_GAPS.length];
|
||
tl.set(el, { opacity: 1 }, w);
|
||
tl.fromTo(
|
||
el,
|
||
{ color: "#767676" },
|
||
{ color: "#141414", duration: 0.2667, ease: "none" },
|
||
w,
|
||
);
|
||
});
|
||
|
||
/* stream ends: stop button returns to send */
|
||
tl.set("#acr-btn-stop", { autoAlpha: 0 }, w + 0.4667);
|
||
tl.set("#acr-btn-send-black", { autoAlpha: 1 }, w + 0.4667);
|
||
|
||
/* end card */
|
||
tl.set("#acr-endcard-inner", { opacity: 0 }, 0.001);
|
||
tl.fromTo(
|
||
"#acr-endcard-inner",
|
||
{ opacity: 0 },
|
||
{ opacity: 1, duration: 0.3167, ease: "none" },
|
||
15.8333,
|
||
);
|
||
|
||
window.__timelines["ai-chat-reveal"] = tl;
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
</VariablesExplorer>
|
||
|
||
## Install
|
||
|
||
<InstallCommand command="npx hyperframes add ai-chat-reveal" item="ai-chat-reveal" />
|
||
|
||
That writes `compositions/ai-chat-reveal.html`, plus 1 supporting file under `assets/`.
|
||
|
||
## Add it to your video
|
||
|
||
It runs for 19.3333 seconds at 1080×1920. Paste this into your composition:
|
||
|
||
```html index.html
|
||
<div
|
||
data-composition-id="ai-chat-reveal"
|
||
data-composition-src="compositions/ai-chat-reveal.html"
|
||
data-start="0"
|
||
data-duration="19.3333"
|
||
data-track-index="1"
|
||
data-width="1080"
|
||
data-height="1920"
|
||
></div>
|
||
```
|
||
|
||
Move it in time with `data-start`. Put it on a different timeline row with
|
||
`data-track-index`. See [data attributes](/concepts/data-attributes) for the rest.
|
||
|
||
## Variables
|
||
|
||
Every one of these has a default, so the piece works untouched. Set the ones you
|
||
want to change on the element:
|
||
|
||
| Variable | Default | Accepts | What it does |
|
||
| --- | --- | --- | --- |
|
||
| `botName` | `Assistant` | string | Title in the chat header. |
|
||
| `userMessage` | `How do I turn my HTML into real video?` | string | The question typed on the keyboard and sent. Around 40 characters keeps the measured pacing. |
|
||
| `answer1` | `You do not need an editor. HyperFrames renders the HTML you already write into deterministic, pixel-perfect video.` | string | First streamed paragraph. |
|
||
| `answer2` | `It is markup, not magic.` | string | Short second beat. |
|
||
| `answer3` | `What you get out of the box:` | string | Lead-in to the list. |
|
||
| `bullet1` | `A catalog of motion primitives you install and own` | string | First list item. |
|
||
| `bullet2` | `GSAP timelines that seek to any frame` | string | Second list item. |
|
||
| `bullet3` | `4K renders from a single CLI command` | string | Third list item. |
|
||
| `ecHeadline` | `It's not magic.|It's HTML.` | string | Closing card headline. A | breaks the line. |
|
||
| `ecSub` | `Open-source video rendering — write HTML, ship pixel-perfect video.` | string | Supporting sentence on the closing card. |
|
||
| `ecCta` | `Try HyperFrames` | string | Label on the closing card button. |
|
||
| `ecFooter` | `HYPERFRAMES.HEYGEN.COM` | string | Letter-spaced line at the very bottom. |
|
||
|
||
Set them with `data-variable-values` on the element that mounts it. These are the
|
||
defaults, so this behaves exactly like the preview above until you change one:
|
||
|
||
```html wrap
|
||
<div
|
||
data-composition-id="ai-chat-reveal"
|
||
data-composition-src="compositions/ai-chat-reveal.html"
|
||
data-variable-values='{"botName":"Assistant","userMessage":"How do I turn my HTML into real video?","answer1":"You do not need an editor. HyperFrames renders the HTML you already write into deterministic, pixel-perfect video.","answer2":"It is markup, not magic.","answer3":"What you get out of the box:","bullet1":"A catalog of motion primitives you install and own","bullet2":"GSAP timelines that seek to any frame","bullet3":"4K renders from a single CLI command","ecHeadline":"It's not magic.|It's HTML.","ecSub":"Open-source video rendering — write HTML, ship pixel-perfect video.","ecCta":"Try HyperFrames","ecFooter":"HYPERFRAMES.HEYGEN.COM"}'
|
||
></div>
|
||
```
|
||
|
||
## Source
|
||
|
||
<Accordion title={`ai-chat-reveal.html`}>
|
||
|
||
```html
|
||
<!doctype html>
|
||
<html
|
||
lang="en"
|
||
data-composition-variables='[
|
||
{ "id": "botName", "type": "string", "role": "content", "label": "Assistant name", "description": "Title in the chat header.", "default": "Assistant" },
|
||
{ "id": "userMessage", "type": "string", "role": "content", "label": "User message", "description": "The question typed on the keyboard and sent. Around 40 characters keeps the measured pacing.", "default": "How do I turn my HTML into real video?" },
|
||
{ "id": "answer1", "type": "string", "role": "content", "label": "Answer paragraph 1", "description": "First streamed paragraph.", "default": "You do not need an editor. HyperFrames renders the HTML you already write into deterministic, pixel-perfect video." },
|
||
{ "id": "answer2", "type": "string", "role": "content", "label": "Answer paragraph 2", "description": "Short second beat.", "default": "It is markup, not magic." },
|
||
{ "id": "answer3", "type": "string", "role": "content", "label": "Answer paragraph 3", "description": "Lead-in to the list.", "default": "What you get out of the box:" },
|
||
{ "id": "bullet1", "type": "string", "role": "content", "label": "Bullet 1", "description": "First list item.", "default": "A catalog of motion primitives you install and own" },
|
||
{ "id": "bullet2", "type": "string", "role": "content", "label": "Bullet 2", "description": "Second list item.", "default": "GSAP timelines that seek to any frame" },
|
||
{ "id": "bullet3", "type": "string", "role": "content", "label": "Bullet 3", "description": "Third list item.", "default": "4K renders from a single CLI command" },
|
||
{ "id": "ecHeadline", "type": "string", "role": "content", "label": "End-card headline", "description": "Closing card headline. A | breaks the line.", "default": "It's not magic.|It's HTML." },
|
||
{ "id": "ecSub", "type": "string", "role": "content", "label": "End-card subline", "description": "Supporting sentence on the closing card.", "default": "Open-source video rendering — write HTML, ship pixel-perfect video." },
|
||
{ "id": "ecCta", "type": "string", "role": "content", "label": "End-card CTA", "description": "Label on the closing card button.", "default": "Try HyperFrames" },
|
||
{ "id": "ecFooter", "type": "string", "role": "content", "label": "End-card footer", "description": "Letter-spaced line at the very bottom.", "default": "HYPERFRAMES.HEYGEN.COM" }
|
||
]'
|
||
>
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=1080, height=1920" />
|
||
<title>AI Chat Reveal</title>
|
||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
html,
|
||
body {
|
||
width: 1080px;
|
||
height: 1920px;
|
||
overflow: hidden;
|
||
background: #000;
|
||
}
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
|
||
}
|
||
/* The measured 750x1624 device UI is scaled uniformly into a standard
|
||
1080x1920 portrait canvas so its keyboard geometry stays pixel-true. */
|
||
#acr-root {
|
||
position: relative;
|
||
width: 1080px;
|
||
height: 1920px;
|
||
overflow: hidden;
|
||
}
|
||
.clip {
|
||
position: absolute;
|
||
inset: 0;
|
||
overflow: hidden;
|
||
}
|
||
#acr-chat {
|
||
background: #fdfdfd;
|
||
}
|
||
.acr-stage {
|
||
position: absolute;
|
||
left: 96.6502px;
|
||
top: 0;
|
||
width: 750px;
|
||
height: 1624px;
|
||
transform: scale(1.18226601);
|
||
transform-origin: top left;
|
||
}
|
||
#acr-chat-bg {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: #fdfdfd;
|
||
}
|
||
|
||
/* status bar */
|
||
#acr-statusbar {
|
||
position: absolute;
|
||
top: 14px;
|
||
left: 0;
|
||
right: 0;
|
||
height: 44px;
|
||
}
|
||
#acr-clock {
|
||
position: absolute;
|
||
left: 39px;
|
||
top: 9px;
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
letter-spacing: 2.4px;
|
||
font-variant-numeric: tabular-nums;
|
||
color: #0d0d0d;
|
||
}
|
||
#acr-sicons {
|
||
position: absolute;
|
||
right: 26px;
|
||
top: 8px;
|
||
display: flex;
|
||
gap: 9px;
|
||
align-items: center;
|
||
}
|
||
|
||
/* header */
|
||
#acr-header {
|
||
position: absolute;
|
||
top: 64px;
|
||
left: 0;
|
||
right: 0;
|
||
height: 52px;
|
||
}
|
||
#acr-hleft {
|
||
position: absolute;
|
||
left: 28px;
|
||
top: 12px;
|
||
}
|
||
#acr-htitle {
|
||
position: absolute;
|
||
left: 0;
|
||
right: 48px;
|
||
text-align: center;
|
||
top: 13px;
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
color: #0d0d0d;
|
||
}
|
||
.acr-hicons {
|
||
position: absolute;
|
||
right: 28px;
|
||
top: 14px;
|
||
display: flex;
|
||
gap: 26px;
|
||
align-items: center;
|
||
}
|
||
#acr-hicons-b {
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
|
||
/* user bubble */
|
||
#acr-bubble {
|
||
position: absolute;
|
||
top: 129px;
|
||
right: 32px;
|
||
max-width: 544px;
|
||
background: #f3f3f3;
|
||
border-radius: 34px;
|
||
padding: 20px 30px;
|
||
font-size: 27px;
|
||
line-height: 38.6px;
|
||
color: #111;
|
||
letter-spacing: 1.25px;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
|
||
/* answer */
|
||
#acr-answer {
|
||
position: absolute;
|
||
top: 267px;
|
||
left: 33px;
|
||
width: 662px;
|
||
font-size: 27px;
|
||
line-height: 38.6px;
|
||
color: #141414;
|
||
letter-spacing: 1.25px;
|
||
}
|
||
#acr-answer .acr-ap {
|
||
margin: 0 0 15.5px 0;
|
||
}
|
||
#acr-answer .acr-ali {
|
||
display: flex;
|
||
margin: 0 0 6.5px 0;
|
||
}
|
||
#acr-answer .acr-mark {
|
||
width: 30px;
|
||
flex: 0 0 30px;
|
||
text-align: center;
|
||
font-size: 18px;
|
||
line-height: 38.6px;
|
||
}
|
||
#acr-answer .acr-alitext {
|
||
flex: 1;
|
||
}
|
||
.acr-w {
|
||
opacity: 0;
|
||
}
|
||
#acr-dot {
|
||
position: absolute;
|
||
left: 32px;
|
||
top: 279px;
|
||
width: 15px;
|
||
height: 15px;
|
||
border-radius: 50%;
|
||
background: #646464;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
|
||
/* composer (rest dock; rides keyboard via transform) */
|
||
#acr-composer {
|
||
position: absolute;
|
||
left: 30px;
|
||
right: 30px;
|
||
bottom: 31px;
|
||
}
|
||
#acr-pill {
|
||
position: relative;
|
||
width: 100%;
|
||
min-height: 81px;
|
||
background: #fff;
|
||
border: 2px solid #ececec;
|
||
border-radius: 41px;
|
||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 13px 160px 13px 78px;
|
||
}
|
||
#acr-plusi {
|
||
position: absolute;
|
||
left: 30px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
#acr-ph {
|
||
position: absolute;
|
||
left: 78px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
color: #767676;
|
||
font-size: 28px;
|
||
letter-spacing: 1.25px;
|
||
}
|
||
#acr-ctextwrap {
|
||
width: 100%;
|
||
min-height: 38px;
|
||
}
|
||
#acr-ctext {
|
||
font-size: 29px;
|
||
line-height: 38px;
|
||
color: #0d0d0d;
|
||
letter-spacing: 1.25px;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
#acr-caret {
|
||
display: inline-block;
|
||
width: 3px;
|
||
height: 30px;
|
||
margin-left: 2px;
|
||
border-radius: 1.5px;
|
||
background: #0d0d0d;
|
||
vertical-align: -4px;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
#acr-cmic {
|
||
position: absolute;
|
||
right: 80px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
.acr-cbtn {
|
||
position: absolute;
|
||
right: 14px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 52px;
|
||
height: 52px;
|
||
border-radius: 50%;
|
||
display: grid;
|
||
place-items: center;
|
||
}
|
||
#acr-btn-send-grey {
|
||
background: #ececec;
|
||
}
|
||
#acr-btn-send-black {
|
||
background: #0d0d0d;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
#acr-btn-stop {
|
||
background: #0d0d0d;
|
||
visibility: hidden;
|
||
opacity: 0;
|
||
}
|
||
#acr-btn-stop .acr-sq {
|
||
width: 19px;
|
||
height: 19px;
|
||
border-radius: 5px;
|
||
background: #fff;
|
||
}
|
||
|
||
/* keyboard: geometry and #d2d5e0 ground measured from the reference */
|
||
#acr-keyboard {
|
||
position: absolute;
|
||
left: 0;
|
||
bottom: 0;
|
||
width: 750px;
|
||
height: 482px;
|
||
background: #d2d5e0;
|
||
}
|
||
#acr-suggest {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 74px;
|
||
display: flex;
|
||
}
|
||
#acr-suggest .acr-sug {
|
||
flex: 1;
|
||
display: grid;
|
||
place-items: center;
|
||
font-size: 29px;
|
||
color: #0d0d0d;
|
||
position: relative;
|
||
}
|
||
#acr-suggest .acr-sug + .acr-sug::before {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 16px;
|
||
bottom: 16px;
|
||
width: 1.5px;
|
||
background: #bcbabf;
|
||
}
|
||
.acr-key {
|
||
position: absolute;
|
||
height: 74px;
|
||
background: #fdfdfd;
|
||
border-radius: 10px;
|
||
box-shadow: 0 2px 0 #8b8a8f;
|
||
display: grid;
|
||
place-items: center;
|
||
font-size: 32px;
|
||
color: #000;
|
||
}
|
||
.acr-gkey {
|
||
background: #aeacaf;
|
||
}
|
||
.acr-num,
|
||
.acr-spc {
|
||
font-size: 27px;
|
||
}
|
||
.acr-kbstrip {
|
||
position: absolute;
|
||
bottom: 10px;
|
||
left: 0;
|
||
right: 0;
|
||
height: 52px;
|
||
}
|
||
.acr-kglobe {
|
||
position: absolute;
|
||
left: 48px;
|
||
top: 21px;
|
||
}
|
||
.acr-kmic {
|
||
position: absolute;
|
||
right: 52px;
|
||
top: 23px;
|
||
}
|
||
|
||
/* end card: the HyperFrames closing card, on the family's dark ground */
|
||
#acr-endcard-inner {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: linear-gradient(180deg, #14110e 0%, #221b13 100%);
|
||
opacity: 0;
|
||
}
|
||
#acr-eclogo {
|
||
position: absolute;
|
||
left: 255px;
|
||
top: 112px;
|
||
width: 240px;
|
||
height: 72px;
|
||
}
|
||
#acr-ecstar {
|
||
position: absolute;
|
||
left: 610px;
|
||
top: 230px;
|
||
}
|
||
#acr-ecvideo {
|
||
position: absolute;
|
||
left: 222px;
|
||
top: 336px;
|
||
width: 283px;
|
||
height: 454px;
|
||
border-radius: 36px;
|
||
background: linear-gradient(165deg, #0f3a2c 0%, #0a9c6b 78%, #3ce6ac 100%);
|
||
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
|
||
}
|
||
#acr-ecvideo .acr-play {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 108px;
|
||
height: 108px;
|
||
border-radius: 50%;
|
||
background: rgba(253, 253, 253, 0.94);
|
||
display: grid;
|
||
place-items: center;
|
||
}
|
||
#acr-echead {
|
||
position: absolute;
|
||
top: 946px;
|
||
left: 0;
|
||
right: 0;
|
||
text-align: center;
|
||
font-weight: 700;
|
||
font-size: 57px;
|
||
line-height: 58px;
|
||
color: #f7ece5;
|
||
letter-spacing: 0.5px;
|
||
}
|
||
#acr-ecsub {
|
||
position: absolute;
|
||
top: 1084px;
|
||
left: 65px;
|
||
right: 65px;
|
||
text-align: center;
|
||
font-weight: 500;
|
||
font-size: 31px;
|
||
line-height: 40px;
|
||
color: #cfc4b8;
|
||
}
|
||
#acr-eccta {
|
||
position: absolute;
|
||
left: 160px;
|
||
top: 1406px;
|
||
width: 429px;
|
||
height: 87px;
|
||
background: #3ce6ac;
|
||
border-radius: 44px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 22px;
|
||
}
|
||
#acr-eccta .acr-lbl {
|
||
color: #0d0d0d;
|
||
font-weight: 700;
|
||
font-size: 33px;
|
||
letter-spacing: 0.3px;
|
||
}
|
||
#acr-ecfoot {
|
||
position: absolute;
|
||
top: 1536px;
|
||
left: 0;
|
||
right: 0;
|
||
text-align: center;
|
||
font-weight: 700;
|
||
font-size: 25px;
|
||
letter-spacing: 4px;
|
||
color: #3ce6ac;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div
|
||
id="acr-root"
|
||
data-composition-id="ai-chat-reveal"
|
||
data-start="0"
|
||
data-width="1080"
|
||
data-height="1920"
|
||
data-duration="19.3333"
|
||
>
|
||
<section id="acr-chat" class="clip" data-start="0" data-duration="16.9" data-track-index="1">
|
||
<div class="acr-stage">
|
||
<div id="acr-chat-bg"></div>
|
||
|
||
<div id="acr-statusbar">
|
||
<div id="acr-clock">11:42</div>
|
||
<div id="acr-sicons">
|
||
<svg width="30" height="20" viewBox="0 0 20 12" fill="#0d0d0d">
|
||
<rect x="0" y="7" width="3" height="4" rx="1" />
|
||
<rect x="5" y="5" width="3" height="6" rx="1" />
|
||
<rect x="10" y="2.6" width="3" height="8.4" rx="1" />
|
||
<rect x="15" y="0.5" width="3" height="10.5" rx="1" /></svg
|
||
><svg
|
||
width="30"
|
||
height="21"
|
||
viewBox="0 0 22 15"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="2.2"
|
||
stroke-linecap="round"
|
||
>
|
||
<path d="M2 5 C7 -0.5 15 -0.5 20 5" fill="none" />
|
||
<path d="M5.5 8.6 C9 5 13 5 16.5 8.6" />
|
||
<path d="M9.2 12 C10.4 11 11.6 11 12.8 12" /></svg
|
||
><svg width="46" height="22" viewBox="0 0 30 14" fill="none">
|
||
<rect
|
||
x="0.8"
|
||
y="0.8"
|
||
width="25"
|
||
height="12.4"
|
||
rx="3.6"
|
||
stroke="#0d0d0d"
|
||
stroke-opacity="0.32"
|
||
stroke-width="1.2"
|
||
/>
|
||
<rect x="2.4" y="2.4" width="22.4" height="9.2" rx="2.4" fill="#0d0d0d" />
|
||
<path d="M28 4.6 v4.8 a2.4 2.4 0 0 0 0 -4.8" fill="#0d0d0d" fill-opacity="0.45" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="acr-header">
|
||
<div id="acr-hleft">
|
||
<svg
|
||
width="29"
|
||
height="29"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.9"
|
||
stroke-linecap="round"
|
||
>
|
||
<path d="M4 8 H20 M4 15 H12" />
|
||
</svg>
|
||
</div>
|
||
<div id="acr-htitle">Assistant</div>
|
||
<div class="acr-hicons" id="acr-hicons-a">
|
||
<svg
|
||
width="28"
|
||
height="28"
|
||
viewBox="0 0 26 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.7"
|
||
stroke-linecap="round"
|
||
>
|
||
<circle cx="10" cy="8" r="4" />
|
||
<path d="M3 21 C3 16 6.5 14 10 14 C13.5 14 17 16 17 21" />
|
||
<path d="M20 6 V12 M17 9 H23" /></svg
|
||
><svg
|
||
width="26"
|
||
height="26"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.7"
|
||
stroke-linecap="round"
|
||
stroke-dasharray="2.4 3.4"
|
||
>
|
||
<circle cx="12" cy="12" r="9" />
|
||
</svg>
|
||
</div>
|
||
<div class="acr-hicons" id="acr-hicons-b">
|
||
<svg
|
||
width="23"
|
||
height="23"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.7"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<path
|
||
d="M4 20 L5 15.5 L16.5 4 C17.6 2.9 19.4 2.9 20.5 4 C21.6 5.1 21.6 6.9 20.5 8 L9 19.5 L4 20 Z"
|
||
/></svg
|
||
><svg width="34" height="34" viewBox="0 0 24 24" fill="#0d0d0d">
|
||
<circle cx="5" cy="12" r="1.7" />
|
||
<circle cx="12" cy="12" r="1.7" />
|
||
<circle cx="19" cy="12" r="1.7" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="acr-bubble">How do I turn my HTML into real video?</div>
|
||
|
||
<div id="acr-dot"></div>
|
||
<div id="acr-answer" data-layout-allow-occlusion></div>
|
||
|
||
<div id="acr-composer">
|
||
<div id="acr-pill">
|
||
<div id="acr-plusi">
|
||
<svg
|
||
width="22"
|
||
height="22"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="1.9"
|
||
stroke-linecap="round"
|
||
>
|
||
<path d="M12 5 V19 M5 12 H19" />
|
||
</svg>
|
||
</div>
|
||
<div id="acr-ph" data-layout-allow-overlap data-layout-allow-occlusion>
|
||
Ask anything
|
||
</div>
|
||
<div id="acr-ctextwrap"><span id="acr-ctext"></span><span id="acr-caret"></span></div>
|
||
<div id="acr-cmic">
|
||
<svg
|
||
width="15"
|
||
height="22"
|
||
viewBox="0 0 24 34"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="2"
|
||
stroke-linecap="round"
|
||
>
|
||
<rect x="8" y="2" width="8" height="16" rx="4" fill="#0d0d0d" stroke="none" />
|
||
<path d="M4 14 a8 8 0 0 0 16 0 M12 22 V28 M7 31 H17" stroke-width="2.2" />
|
||
</svg>
|
||
</div>
|
||
<div class="acr-cbtn" id="acr-btn-send-grey">
|
||
<svg
|
||
width="26"
|
||
height="26"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#b6b6b6"
|
||
stroke-width="2.6"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<path d="M12 19 V6 M6.5 11 L12 5.5 L17.5 11" />
|
||
</svg>
|
||
</div>
|
||
<div class="acr-cbtn" id="acr-btn-send-black">
|
||
<svg
|
||
width="26"
|
||
height="26"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#fff"
|
||
stroke-width="2.6"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<path d="M12 19 V6 M6.5 11 L12 5.5 L17.5 11" />
|
||
</svg>
|
||
</div>
|
||
<div class="acr-cbtn" id="acr-btn-stop"><div class="acr-sq"></div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="acr-keyboard">
|
||
<div id="acr-suggest">
|
||
<div class="acr-sug">How</div>
|
||
<div class="acr-sug">Can</div>
|
||
<div class="acr-sug">My</div>
|
||
</div>
|
||
<div id="acr-keys"></div>
|
||
<div class="acr-kbstrip">
|
||
<span class="acr-kglobe"
|
||
><svg
|
||
width="30"
|
||
height="30"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="#000"
|
||
stroke-width="2.6"
|
||
>
|
||
<circle cx="12" cy="12" r="9.6" />
|
||
<path
|
||
d="M2.4 12 H21.6 M12 2.4 C7.8 6.8 7.8 17.2 12 21.6 C16.2 17.2 16.2 6.8 12 2.4 M4 7 H20 M4 17 H20"
|
||
stroke-width="2.2"
|
||
/></svg></span
|
||
><span class="acr-kmic"
|
||
><svg
|
||
width="16"
|
||
height="25"
|
||
viewBox="0 0 24 34"
|
||
preserveAspectRatio="none"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="3.9"
|
||
stroke-linecap="round"
|
||
>
|
||
<rect
|
||
x="5.5"
|
||
y="1"
|
||
width="13"
|
||
height="17.5"
|
||
rx="6.5"
|
||
fill="#0d0d0d"
|
||
stroke="none"
|
||
/>
|
||
<path d="M2.5 14 a9.5 9.5 0 0 0 19 0 M12 23.5 V28.5 M5.5 32 H18.5" /></svg
|
||
></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section
|
||
id="acr-endcard"
|
||
class="clip"
|
||
data-start="15.8"
|
||
data-duration="3.5333"
|
||
data-track-index="2"
|
||
>
|
||
<div id="acr-endcard-inner">
|
||
<div class="acr-stage">
|
||
<img id="acr-eclogo" src="assets/hyperframes-logo-white.svg" alt="HyperFrames" />
|
||
<svg id="acr-ecstar" width="80" height="80" viewBox="0 0 80 80">
|
||
<g stroke="#2f6b57" stroke-width="8.5" stroke-linecap="round">
|
||
<line x1="47" y1="40" x2="77" y2="40" />
|
||
<line x1="46.5" y1="42.7" x2="74.2" y2="54.2" />
|
||
<line x1="44.9" y1="44.9" x2="66.2" y2="66.2" />
|
||
<line x1="42.7" y1="46.5" x2="54.2" y2="74.2" />
|
||
<line x1="40" y1="47" x2="40" y2="77" />
|
||
<line x1="37.3" y1="46.5" x2="25.8" y2="74.2" />
|
||
<line x1="35.1" y1="44.9" x2="13.8" y2="66.2" />
|
||
<line x1="33.5" y1="42.7" x2="5.8" y2="54.2" />
|
||
<line x1="33" y1="40" x2="3" y2="40" />
|
||
<line x1="33.5" y1="37.3" x2="5.8" y2="25.8" />
|
||
<line x1="35.1" y1="35.1" x2="13.8" y2="13.8" />
|
||
<line x1="37.3" y1="33.5" x2="25.8" y2="5.8" />
|
||
<line x1="40" y1="33" x2="40" y2="3" />
|
||
<line x1="42.7" y1="33.5" x2="54.2" y2="5.8" />
|
||
<line x1="44.9" y1="35.1" x2="66.2" y2="13.8" />
|
||
<line x1="46.5" y1="37.3" x2="74.2" y2="25.8" />
|
||
</g>
|
||
</svg>
|
||
<div id="acr-ecvideo">
|
||
<div class="acr-play">
|
||
<svg width="40" height="46" viewBox="0 0 44 48" fill="none">
|
||
<path
|
||
d="M40.5 20.6 C43.2 22.1 43.2 25.9 40.5 27.4 L6.2 46.6 C3.5 48.1 0.2 46.2 0.2 43.2 L0.2 4.8 C0.2 1.8 3.5 -0.1 6.2 1.4 Z"
|
||
fill="#0d0d0d"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
<div id="acr-echead">It's not magic.<br />It's HTML.</div>
|
||
<div id="acr-ecsub">
|
||
Open-source video rendering — write HTML, ship pixel-perfect video.
|
||
</div>
|
||
<div id="acr-eccta">
|
||
<span class="acr-lbl">Try HyperFrames</span
|
||
><svg
|
||
width="30"
|
||
height="34"
|
||
viewBox="0 0 16 24"
|
||
fill="none"
|
||
stroke="#0d0d0d"
|
||
stroke-width="2.6"
|
||
stroke-linecap="round"
|
||
stroke-linejoin="round"
|
||
>
|
||
<path d="M4 3 L13 12 L4 21" />
|
||
</svg>
|
||
</div>
|
||
<div id="acr-ecfoot">HYPERFRAMES.HEYGEN.COM</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<script>
|
||
(function () {
|
||
"use strict";
|
||
|
||
/* -------- variables -------- */
|
||
var vars =
|
||
window.__hyperframes && typeof window.__hyperframes.getVariables === "function"
|
||
? window.__hyperframes.getVariables()
|
||
: {};
|
||
|
||
function text(value, fallback, max) {
|
||
if (typeof value !== "string") return fallback;
|
||
var t = value.trim();
|
||
if (!t) return fallback;
|
||
return t.length > max ? t.slice(0, max) : t;
|
||
}
|
||
|
||
var botName = text(vars.botName, "Assistant", 24);
|
||
var userMessage = text(vars.userMessage, "How do I turn my HTML into real video?", 60);
|
||
var answer1 = text(
|
||
vars.answer1,
|
||
"You do not need an editor. HyperFrames renders the HTML you already write into deterministic, pixel-perfect video.",
|
||
220,
|
||
);
|
||
var answer2 = text(vars.answer2, "It is markup, not magic.", 120);
|
||
var answer3 = text(vars.answer3, "What you get out of the box:", 120);
|
||
var bullets = [
|
||
text(vars.bullet1, "A catalog of motion primitives you install and own", 90),
|
||
text(vars.bullet2, "GSAP timelines that seek to any frame", 90),
|
||
text(vars.bullet3, "4K renders from a single CLI command", 90),
|
||
];
|
||
|
||
document.getElementById("acr-htitle").textContent = botName;
|
||
document.getElementById("acr-bubble").textContent = userMessage;
|
||
document.getElementById("acr-echead").innerHTML = "";
|
||
text(vars.ecHeadline, "It's not magic.|It's HTML.", 60)
|
||
.split("|")
|
||
.forEach(function (line, i) {
|
||
var head = document.getElementById("acr-echead");
|
||
if (i > 0) head.appendChild(document.createElement("br"));
|
||
head.appendChild(document.createTextNode(line));
|
||
});
|
||
document.getElementById("acr-ecsub").textContent = text(
|
||
vars.ecSub,
|
||
"Open-source video rendering — write HTML, ship pixel-perfect video.",
|
||
140,
|
||
);
|
||
document.querySelector("#acr-eccta .acr-lbl").textContent = text(
|
||
vars.ecCta,
|
||
"Try HyperFrames",
|
||
30,
|
||
);
|
||
document.getElementById("acr-ecfoot").textContent = text(
|
||
vars.ecFooter,
|
||
"HYPERFRAMES.HEYGEN.COM",
|
||
40,
|
||
);
|
||
|
||
/* -------- build the answer DOM: paragraphs of word spans, then bullets -------- */
|
||
var answerEl = document.getElementById("acr-answer");
|
||
var wordEls = [];
|
||
function addPara(str) {
|
||
var p = document.createElement("p");
|
||
p.className = "acr-ap";
|
||
str.split(/\s+/).forEach(function (word, i) {
|
||
if (i > 0) p.appendChild(document.createTextNode(" "));
|
||
var s = document.createElement("span");
|
||
s.className = "acr-w";
|
||
s.textContent = word;
|
||
p.appendChild(s);
|
||
wordEls.push(s);
|
||
});
|
||
answerEl.appendChild(p);
|
||
}
|
||
addPara(answer1);
|
||
addPara(answer2);
|
||
addPara(answer3);
|
||
bullets.forEach(function (b) {
|
||
var row = document.createElement("div");
|
||
row.className = "acr-ali";
|
||
var mark = document.createElement("span");
|
||
mark.className = "acr-mark acr-w";
|
||
mark.textContent = "•";
|
||
row.appendChild(mark);
|
||
wordEls.push(mark);
|
||
var body = document.createElement("div");
|
||
body.className = "acr-alitext";
|
||
b.split(/\s+/).forEach(function (word, i) {
|
||
if (i > 0) body.appendChild(document.createTextNode(" "));
|
||
var s = document.createElement("span");
|
||
s.className = "acr-w";
|
||
s.textContent = word;
|
||
body.appendChild(s);
|
||
wordEls.push(s);
|
||
});
|
||
row.appendChild(body);
|
||
answerEl.appendChild(row);
|
||
});
|
||
|
||
/* -------- build the keyboard: measured key geometry -------- */
|
||
var keysEl = document.getElementById("acr-keys");
|
||
var ROWS = [
|
||
{ top: 83, left: 13, letters: "qwertyuiop" },
|
||
{ top: 173, left: 48, letters: "asdfghjkl" },
|
||
{ top: 263, left: 123, letters: "zxcvbnm" },
|
||
];
|
||
ROWS.forEach(function (row) {
|
||
row.letters.split("").forEach(function (ch, i) {
|
||
var k = document.createElement("div");
|
||
k.className = "acr-key";
|
||
k.style.left = row.left + i * 73.7 + "px";
|
||
k.style.top = row.top + "px";
|
||
k.style.width = "62px";
|
||
k.textContent = ch;
|
||
keysEl.appendChild(k);
|
||
});
|
||
});
|
||
[
|
||
{
|
||
left: 13,
|
||
top: 263,
|
||
width: 97,
|
||
cls: " acr-gkey",
|
||
html: '<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="1.6" stroke-linejoin="round"><path d="M12 4 L4.5 12 H8.5 V17 H15.5 V12 H19.5 Z"/></svg>',
|
||
},
|
||
{
|
||
left: 640,
|
||
top: 263,
|
||
width: 98,
|
||
cls: " acr-gkey",
|
||
html: '<svg width="31" height="24" viewBox="0 0 28 20" fill="none" stroke="#000" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"><path d="M9 2 H26 V18 H9 L1.5 10 Z"/><path d="M13 6.5 L20 13.5 M20 6.5 L13 13.5"/></svg>',
|
||
},
|
||
{ left: 13, top: 353, width: 97, cls: " acr-gkey acr-num", html: "123" },
|
||
{
|
||
left: 118,
|
||
top: 353,
|
||
width: 86,
|
||
cls: "",
|
||
html: '<svg width="27" height="27" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="1.4" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><circle cx="9" cy="10" r="0.6" fill="#000"/><circle cx="15" cy="10" r="0.6" fill="#000"/><path d="M8 14.5 C9.5 16.5 14.5 16.5 16 14.5"/></svg>',
|
||
},
|
||
{ left: 217, top: 353, width: 389, cls: " acr-spc", html: "space" },
|
||
{
|
||
left: 614,
|
||
top: 353,
|
||
width: 124,
|
||
cls: " acr-gkey",
|
||
html: '<svg width="27" height="27" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M19 5 V11 H6"/><path d="M9.5 7.5 L6 11 L9.5 14.5"/></svg>',
|
||
},
|
||
].forEach(function (spec) {
|
||
var k = document.createElement("div");
|
||
k.className = "acr-key" + spec.cls;
|
||
k.style.left = spec.left + "px";
|
||
k.style.top = spec.top + "px";
|
||
k.style.width = spec.width + "px";
|
||
k.innerHTML = spec.html;
|
||
keysEl.appendChild(k);
|
||
});
|
||
|
||
/* -------- timeline -------- */
|
||
window.__timelines = window.__timelines || {};
|
||
var tl = gsap.timeline({ paused: true });
|
||
|
||
/* keystroke and token rhythms, measured from the reference and cycled */
|
||
var KEY_GAPS = [
|
||
0.1, 0.033, 0.2, 0.133, 0.2, 0.033, 0.067, 0.033, 0.1, 0.067, 0.033, 0.067, 0.067, 0.067,
|
||
0.133, 0.067, 0.033, 0.067, 0.1, 0.1, 0.067, 0.133, 0.1, 0.033, 0.1, 0.033, 0.167, 0.033,
|
||
0.1, 0.1, 0.067, 0.133, 0.033, 0.067, 0.1, 0.033, 0.1, 0.067,
|
||
];
|
||
var WORD_GAPS = [
|
||
0.167, 0.1, 0.0, 0.367, 0.0, 0.167, 0.133, 0.1, 0.1, 0.133, 0.167, 0.133, 0.0, 0.233,
|
||
0.167, 0.1, 0.0, 0.133, 0.133, 0.1, 0.167, 0.133, 0.1, 0.133, 0.167, 0.1, 0.133, 0.1,
|
||
0.133,
|
||
];
|
||
|
||
/* keyboard rises, composer rides it (verbatim anchors) */
|
||
tl.fromTo("#acr-keyboard", { y: 482 }, { y: 0, duration: 0.2667, ease: "power2.out" }, 0.2);
|
||
tl.fromTo(
|
||
"#acr-composer",
|
||
{ y: 0 },
|
||
{ y: -497, duration: 0.2667, ease: "power2.out" },
|
||
0.2,
|
||
);
|
||
|
||
/* typing: two characters land on the first beat, then the measured gaps */
|
||
tl.set("#acr-ctext", { textContent: "", autoAlpha: 0 }, 0.001);
|
||
var TYPE_START = 0.8637;
|
||
tl.set("#acr-ctext", { autoAlpha: 1 }, TYPE_START);
|
||
tl.set("#acr-ph", { autoAlpha: 0 }, TYPE_START);
|
||
tl.set("#acr-btn-send-grey", { autoAlpha: 0 }, TYPE_START);
|
||
tl.set("#acr-btn-send-black", { autoAlpha: 1 }, TYPE_START);
|
||
var t = TYPE_START;
|
||
for (var n = 2; n <= userMessage.length; n += 1) {
|
||
tl.set("#acr-ctext", { textContent: userMessage.slice(0, n) }, t);
|
||
t += KEY_GAPS[(n - 2) % KEY_GAPS.length];
|
||
}
|
||
var typeEnd = t;
|
||
/* caret blinks on a steady half-second while typing */
|
||
tl.set("#acr-caret", { autoAlpha: 0 }, 0.001);
|
||
for (var c = TYPE_START, on = true; c < typeEnd; c += 0.5333, on = !on) {
|
||
tl.set("#acr-caret", { autoAlpha: on ? 1 : 0 }, c);
|
||
}
|
||
|
||
/* send: bubble pops, keyboard drops, stream begins */
|
||
var SEND = typeEnd + 0.1667;
|
||
tl.set("#acr-caret", { autoAlpha: 0 }, SEND);
|
||
tl.set("#acr-ctext", { textContent: "" }, SEND);
|
||
tl.set("#acr-ph", { autoAlpha: 1 }, SEND);
|
||
tl.set("#acr-btn-send-black", { autoAlpha: 0 }, SEND);
|
||
tl.set("#acr-btn-stop", { autoAlpha: 1 }, SEND);
|
||
tl.fromTo(
|
||
"#acr-bubble",
|
||
{ autoAlpha: 0 },
|
||
{ autoAlpha: 1, duration: 0.1667, ease: "power1.out" },
|
||
SEND - 0.03,
|
||
);
|
||
tl.set("#acr-hicons-a", { autoAlpha: 0 }, SEND);
|
||
tl.set("#acr-hicons-b", { autoAlpha: 1 }, SEND);
|
||
tl.to("#acr-keyboard", { y: 482, duration: 0.2667, ease: "power1.inOut" }, SEND - 0.03);
|
||
tl.to("#acr-composer", { y: 0, duration: 0.2667, ease: "power1.inOut" }, SEND - 0.03);
|
||
|
||
/* thinking dot: the measured alpha ramp, then it yields to the words */
|
||
var DOT_RAMP = [
|
||
0.488, 0.53, 0.53, 0.56, 0.608, 0.687, 0.729, 0.771, 0.813, 0.867, 0.904, 0.988, 1,
|
||
];
|
||
var dotStart = SEND + 0.4333;
|
||
tl.set("#acr-dot", { autoAlpha: 0 }, 0.001);
|
||
DOT_RAMP.forEach(function (a, i) {
|
||
tl.set("#acr-dot", { autoAlpha: a }, dotStart + i * 0.0333);
|
||
});
|
||
tl.set("#acr-dot", { autoAlpha: 0 }, dotStart + 0.5667);
|
||
|
||
/* the stream: measured token rhythm, fresh grey inking to full colour */
|
||
var w = dotStart + 0.6333;
|
||
wordEls.forEach(function (el, i) {
|
||
if (i > 0) w += WORD_GAPS[i % WORD_GAPS.length];
|
||
tl.set(el, { opacity: 1 }, w);
|
||
tl.fromTo(
|
||
el,
|
||
{ color: "#767676" },
|
||
{ color: "#141414", duration: 0.2667, ease: "none" },
|
||
w,
|
||
);
|
||
});
|
||
|
||
/* stream ends: stop button returns to send */
|
||
tl.set("#acr-btn-stop", { autoAlpha: 0 }, w + 0.4667);
|
||
tl.set("#acr-btn-send-black", { autoAlpha: 1 }, w + 0.4667);
|
||
|
||
/* end card */
|
||
tl.set("#acr-endcard-inner", { opacity: 0 }, 0.001);
|
||
tl.fromTo(
|
||
"#acr-endcard-inner",
|
||
{ opacity: 0 },
|
||
{ opacity: 1, duration: 0.3167, ease: "none" },
|
||
15.8333,
|
||
);
|
||
|
||
window.__timelines["ai-chat-reveal"] = tl;
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
</Accordion>
|
||
|
||
{/* hf:generated-footer */}
|
||
|
||
Tagged `showcase` `mock-ui` `ai` `chat` `vertical` `ad-template`.
|
||
|
||
Created by Miao Yang.
|
||
|
||
## Related topics
|
||
|
||
- [Browse the complete Catalog](/catalog)
|
||
- [Add assets and Catalog items in Studio](/studio/assets-and-blocks)
|
||
- [Build a richer composition](/go-further)
|