Animated Open Graph / social card template at 1200×630.
Edit these placeholders inline or pass --var NAME=value to hyperframes render.
| Variable | Type | Default | Range |
|---|---|---|---|
{{$BRAND}}Brand | text | HyperFrames | — |
{{$TITLE}}Title | text | HTML is the next video codec. | — |
{{$SUBTITLE}}Subtitle | text | Write HTML, render deterministic MP4. No timeline tool. | — |
{{$URL}}URL | text | hyperframes.dev | — |
{{$ACCENT}}Accent | color | #ff3b1f | — |
{{$INK}}Ink | color | #0a0a0a | — |
{{$BG}}Background | color | #f6f5f1 | — |
<!doctype html>
<html data-duration="6"><head><style>
:root {
--cream:#f6f5f1; --cream-2:#efece4; --ink:#0a0a0a; --mute:#6b6862;
--line:#e3dfd3; --signal:#ff3b1f; --signal-2:#ff6a4a; --frame:#ffb800;
--green:#1f8a5b; --blue:#2b66ff;
}
* { box-sizing: border-box; }
body { margin:0; }
body { background: {{$BG}}; color: {{$INK}}; width: 1200px; height: 630px; margin: 0;
overflow: hidden; font-family: ui-sans-serif, system-ui;
display: grid; grid-template-rows: auto 1fr auto; padding: 60px 72px; }
.hd { display: flex; justify-content: space-between; align-items: center;
font-family: ui-monospace, monospace; font-size: 13px; letter-spacing: .28em;
text-transform: uppercase; color: color-mix(in srgb, {{$INK}} 55%, transparent); }
.dot { width: 10px; height: 10px; border-radius: 50%; background: {{$ACCENT}};
display: inline-block; margin-right: 8px; vertical-align: middle; }
.stage { display: grid; align-content: center; gap: 18px; overflow: hidden; }
.title { font-size: 82px; font-weight: 800; letter-spacing: -.035em; line-height: 1.02;
margin: 0; transform: translateY(40px); opacity: 0; }
.sub { font-size: 26px; font-weight: 500; line-height: 1.35;
color: color-mix(in srgb, {{$INK}} 70%, transparent);
transform: translateY(30px); opacity: 0; margin: 0; max-width: 880px; }
.bar { height: 4px; background: {{$ACCENT}}; width: 0; }
.foot { display: flex; justify-content: space-between; align-items: center;
font-family: ui-monospace, monospace; font-size: 13px; letter-spacing: .28em;
text-transform: uppercase; color: color-mix(in srgb, {{$INK}} 55%, transparent); }
</style></head><body>
<div class="hd"><span><span class="dot"></span>{{$BRAND}}</span><span>OG · 1200 × 630</span></div>
<div class="stage">
<h1 class="title" id="t">{{$TITLE}}</h1>
<p class="sub" id="s">{{$SUBTITLE}}</p>
<div class="bar" id="b"></div>
</div>
<div class="foot"><span>{{$URL}}</span><span id="tc">t 0.0s</span></div>
<script>
var t = document.getElementById('t');
var s = document.getElementById('s');
var b = document.getElementById('b');
var tc = document.getElementById('tc');
function ease(t){ return 1 - Math.pow(1 - Math.min(1, Math.max(0, t)), 3); }
function render(time){
var u1 = ease((time - 0.1) / 0.9);
t.style.transform = 'translateY(' + ((1 - u1) * 40).toFixed(1) + 'px)';
t.style.opacity = u1.toFixed(2);
var u2 = ease((time - 0.45) / 0.9);
s.style.transform = 'translateY(' + ((1 - u2) * 30).toFixed(1) + 'px)';
s.style.opacity = u2.toFixed(2);
var u3 = ease((time - 0.8) / 1.4);
b.style.width = (u3 * 100) + '%';
tc.textContent = 't ' + time.toFixed(1) + 's';
}
addEventListener('hf-seek', function(e){ render(e.detail.time); });
render(0);
</script>
</body></html>