style: apply oxfmt baseline formatting across all source files (#25)

## Summary
- Run `oxfmt .` across the entire codebase to establish formatted baseline
- 299 files changed — mechanical formatting only, no logic changes
- Double quotes, semicolons, 2-space indent, trailing commas, 100 print width

Part 3/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] `pnpm format:check` — all 426 files pass
- [x] `pnpm -r typecheck` — all packages pass
- [x] `pnpm build` — all packages build
- [x] All 348 tests pass
This commit is contained in:
Vance Ingalls
2026-03-23 17:15:14 -07:00
committed by GitHub
parent 323ff8f860
commit 20be2ea1c2
299 changed files with 27750 additions and 16792 deletions
@@ -1,14 +1,17 @@
# HyperFrame Schema Compliance Review
## Executive Summary
- Total files reviewed: 6
- Critical issues: 0
- Overall compliance status: PASS
## Critical Issues
None found.
## Compliance Checklist
- [x] All compositions have `data-width` and `data-height` attributes
- [x] All timelines are finite with duration > 0
- [x] All compositions registered in `window.__timelines`
@@ -26,37 +29,49 @@ None found.
- [x] No infinite or zero-duration timelines
### index.html
**Status**: COMPLIANT
**Issues Found**:
- None.
### compositions/background.html
**Status**: COMPLIANT
**Issues Found**:
- None.
### compositions/captions.html
**Status**: COMPLIANT
**Issues Found**:
- None.
### compositions/aroll.html
**Status**: COMPLIANT
**Issues Found**:
- None.
### compositions/mograph_overlays.html
**Status**: COMPLIANT
**Issues Found**:
- None.
### compositions/hero_moment.html
**Status**: COMPLIANT
**Issues Found**:
- None.
@@ -2,21 +2,21 @@
<div data-composition-id="aroll" data-width="1080" data-height="1920" data-duration="14">
<!-- Grid Background -->
<div class="grid-container">
<div class="grid-line horizontal" style="top: 20%;"></div>
<div class="grid-line horizontal" style="top: 40%;"></div>
<div class="grid-line horizontal" style="top: 60%;"></div>
<div class="grid-line horizontal" style="top: 80%;"></div>
<div class="grid-line vertical" style="left: 20%;"></div>
<div class="grid-line vertical" style="left: 40%;"></div>
<div class="grid-line vertical" style="left: 60%;"></div>
<div class="grid-line vertical" style="left: 80%;"></div>
<div class="grid-line horizontal" style="top: 20%"></div>
<div class="grid-line horizontal" style="top: 40%"></div>
<div class="grid-line horizontal" style="top: 60%"></div>
<div class="grid-line horizontal" style="top: 80%"></div>
<div class="grid-line vertical" style="left: 20%"></div>
<div class="grid-line vertical" style="left: 40%"></div>
<div class="grid-line vertical" style="left: 60%"></div>
<div class="grid-line vertical" style="left: 80%"></div>
</div>
<!-- Video Container -->
<div class="video-frame">
<div class="video-mask">
<video
id="aroll-video"
<video
id="aroll-video"
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/uploaded_assets/c10d5d5c_5e0cbe68f361481f8d2c77b028e84504.mp4"
data-start="0"
data-duration="14"
@@ -71,7 +71,7 @@
/* Full width and height for impact, no padding */
top: 0;
left: 0;
width: 100%;
width: 100%;
height: 100%;
background: #111;
overflow: hidden;
@@ -118,7 +118,7 @@
</style>
<script>
(function() {
(function () {
const tl = gsap.timeline({ paused: true });
const frame = document.querySelector('[data-composition-id="aroll"] .video-frame');
const wipe1 = document.querySelector('[data-composition-id="aroll"] .wipe-line-1');
@@ -126,60 +126,83 @@
// 1. Entrance & Scale Down (0s - 1.5s)
// Starts full screen and scales down slightly to establish the grid
tl.fromTo(frame, {
scale: 1.1,
opacity: 0
}, {
scale: 1.0, /* Fixed scale to fill frame better */
opacity: 1,
duration: 1.5,
ease: 'power4.out'
}, 0);
tl.fromTo(wipe1,
{ opacity: 1, y: -500 },
{ y: 1500, duration: 1.5, ease: 'power2.inOut' },
0
tl.fromTo(
frame,
{
scale: 1.1,
opacity: 0,
},
{
scale: 1.0 /* Fixed scale to fill frame better */,
opacity: 1,
duration: 1.5,
ease: "power4.out",
},
0,
);
tl.fromTo(wipe2,
{ opacity: 1, y: 500 },
{ y: -1500, duration: 1.5, ease: 'power2.inOut' },
0.1
tl.fromTo(
wipe1,
{ opacity: 1, y: -500 },
{ y: 1500, duration: 1.5, ease: "power2.inOut" },
0,
);
tl.fromTo(
wipe2,
{ opacity: 1, y: 500 },
{ y: -1500, duration: 1.5, ease: "power2.inOut" },
0.1,
);
tl.to([wipe1, wipe2], { opacity: 0, duration: 0.3 }, 1.5);
// 2. Ambient Motion (1.5s - 7.319s)
tl.to(frame, {
y: '+=15',
duration: 3,
ease: 'sine.inOut',
repeat: 1,
yoyo: true
}, 1.5);
tl.to(
frame,
{
y: "+=15",
duration: 3,
ease: "sine.inOut",
repeat: 1,
yoyo: true,
},
1.5,
);
// 3. Hero Moment Exit (7.319s - 8.319s)
tl.to(frame, {
scale: 0,
opacity: 0,
duration: 0.8,
ease: 'power3.in'
}, 7.319);
tl.to(
frame,
{
scale: 0,
opacity: 0,
duration: 0.8,
ease: "power3.in",
},
7.319,
);
// 4. Hero Moment Return (12.239s - 13.739s)
tl.to(frame, {
scale: 1.0, /* Fixed return scale */
opacity: 1,
duration: 1.2,
ease: 'back.out(1.2)'
}, 12.239);
tl.to(
frame,
{
scale: 1.0 /* Fixed return scale */,
opacity: 1,
duration: 1.2,
ease: "back.out(1.2)",
},
12.239,
);
// 5. Final Exit (13.8s - 14s)
tl.to(frame, {
opacity: 0,
scale: 0.6,
duration: 0.5,
ease: 'power2.in'
}, 13.5);
tl.to(
frame,
{
opacity: 0,
scale: 0.6,
duration: 0.5,
ease: "power2.in",
},
13.5,
);
window.__timelines["aroll"] = tl;
})();
@@ -1,18 +1,18 @@
<template id="background-template">
<div data-composition-id="background" data-width="1080" data-height="1920" data-duration="14">
<div class="paper-texture"></div>
<!-- Grid Lines Container -->
<div class="grid-container">
<!-- Horizontal Lines -->
<div class="line horizontal h1" style="top: 15%; height: 2px;"></div>
<div class="line horizontal h2" style="top: 45%; height: 6px;"></div>
<div class="line horizontal h3" style="top: 85%; height: 1px;"></div>
<div class="line horizontal h1" style="top: 15%; height: 2px"></div>
<div class="line horizontal h2" style="top: 45%; height: 6px"></div>
<div class="line horizontal h3" style="top: 85%; height: 1px"></div>
<!-- Vertical Lines -->
<div class="line vertical v1" style="left: 20%; width: 4px;"></div>
<div class="line vertical v2" style="left: 65%; width: 2px;"></div>
<div class="line vertical v3" style="left: 80%; width: 8px;"></div>
<div class="line vertical v1" style="left: 20%; width: 4px"></div>
<div class="line vertical v2" style="left: 65%; width: 2px"></div>
<div class="line vertical v3" style="left: 80%; width: 8px"></div>
</div>
<!-- Bauhaus Red Circle -->
@@ -25,7 +25,7 @@
background-color: transparent;
position: relative;
overflow: hidden;
font-family: 'Helvetica', 'Arial', sans-serif;
font-family: "Helvetica", "Arial", sans-serif;
}
/* Subtle Paper Texture */
@@ -71,7 +71,7 @@
position: absolute;
width: 400px;
height: 400px;
background-color: #BE1E2D;
background-color: #be1e2d;
border-radius: 50%;
top: 25%;
left: 60%;
@@ -81,60 +81,84 @@
</style>
<script>
(function() {
(function () {
const tl = gsap.timeline({ paused: true });
// 1. Grid Lines Animation (0s - 1s)
// Staggered entrance for horizontal lines
tl.to('[data-composition-id="background"] .horizontal', {
scaleX: 1,
duration: 0.8,
stagger: 0.15,
ease: "power4.inOut"
}, 0);
tl.to(
'[data-composition-id="background"] .horizontal',
{
scaleX: 1,
duration: 0.8,
stagger: 0.15,
ease: "power4.inOut",
},
0,
);
// Staggered entrance for vertical lines
tl.to('[data-composition-id="background"] .vertical', {
scaleY: 1,
duration: 0.8,
stagger: 0.1,
ease: "power4.inOut"
}, 0.2);
tl.to(
'[data-composition-id="background"] .vertical',
{
scaleY: 1,
duration: 0.8,
stagger: 0.1,
ease: "power4.inOut",
},
0.2,
);
// 2. Circular Element Animation (0.5s - 1.2s)
tl.to('[data-composition-id="background"] .circle-element', {
scale: 1,
duration: 0.7,
ease: "circ.out"
}, 0.5);
tl.to(
'[data-composition-id="background"] .circle-element',
{
scale: 1,
duration: 0.7,
ease: "circ.out",
},
0.5,
);
// 3. Ambient Motion (1s - 14s)
// Subtle drift for the circle
tl.to('[data-composition-id="background"] .circle-element', {
x: -30,
y: 20,
duration: 6.5,
yoyo: true,
repeat: 1,
ease: "sine.inOut"
}, 1);
tl.to(
'[data-composition-id="background"] .circle-element',
{
x: -30,
y: 20,
duration: 6.5,
yoyo: true,
repeat: 1,
ease: "sine.inOut",
},
1,
);
// Subtle weight shift for lines (simulating paper expansion/contraction or focus shift)
tl.to('[data-composition-id="background"] .h2', {
height: "8px",
duration: 6,
yoyo: true,
repeat: 1,
ease: "sine.inOut"
}, 1);
tl.to(
'[data-composition-id="background"] .h2',
{
height: "8px",
duration: 6,
yoyo: true,
repeat: 1,
ease: "sine.inOut",
},
1,
);
tl.to('[data-composition-id="background"] .v3', {
width: "12px",
duration: 5,
yoyo: true,
repeat: 1,
ease: "sine.inOut"
}, 3);
tl.to(
'[data-composition-id="background"] .v3',
{
width: "12px",
duration: 5,
yoyo: true,
repeat: 1,
ease: "sine.inOut",
},
3,
);
// Register the timeline
window.__timelines["background"] = tl;
@@ -7,7 +7,8 @@
<style>
[data-composition-id="captions"] {
background: transparent;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; /* Akzidenz-Grotesk/Futura vibe */
font-family:
"Helvetica Neue", Helvetica, Arial, sans-serif; /* Akzidenz-Grotesk/Futura vibe */
color: #000000;
display: flex;
justify-content: center;
@@ -57,7 +58,7 @@
[data-composition-id="captions"] .word.bold {
font-size: 120px; /* Reduced scale variance for better fit */
font-weight: 900;
color: #BE1E2D; /* Bauhaus Red for emphasis */
color: #be1e2d; /* Bauhaus Red for emphasis */
}
/* Extreme weight for emphasis on keywords */
@@ -87,31 +88,89 @@
</style>
<script>
(function() {
const TRANSCRIPT = [{'text': 'We', 'start': 0.14, 'end': 0.239}, {'text': 'asked', 'start': 0.28, 'end': 0.459}, {'text': 'what', 'start': 0.5, 'end': 0.619}, {'text': 'you', 'start': 0.659, 'end': 0.779}, {'text': 'needed.', 'start': 0.8, 'end': 1.179}, {'text': 'Forty-seven', 'start': 1.199, 'end': 1.619}, {'text': 'percent', 'start': 1.699, 'end': 1.96}, {'text': 'of', 'start': 1.979, 'end': 2.059}, {'text': 'you', 'start': 2.099, 'end': 2.299}, {'text': 'said', 'start': 2.319, 'end': 2.499}, {'text': 'motion', 'start': 2.559, 'end': 2.839}, {'text': 'graphics,', 'start': 2.899, 'end': 3.759}, {'text': 'sixty-two', 'start': 3.799, 'end': 4.159}, {'text': 'percent', 'start': 4.239, 'end': 4.559}, {'text': 'said', 'start': 4.639, 'end': 4.799}, {'text': 'static', 'start': 4.859, 'end': 5.199}, {'text': 'content', 'start': 5.239, 'end': 5.639}, {'text': 'was', 'start': 5.679, 'end': 5.779}, {'text': 'costing', 'start': 5.859, 'end': 6.219}, {'text': 'you', 'start': 6.259, 'end': 6.339}, {'text': 'attention,', 'start': 6.379, 'end': 7.299}, {'text': 'and', 'start': 7.319, 'end': 7.439}, {'text': 'three', 'start': 7.48, 'end': 7.599}, {'text': 'out', 'start': 7.679, 'end': 7.779}, {'text': 'of', 'start': 7.799, 'end': 7.879}, {'text': 'four', 'start': 7.94, 'end': 8.139}, {'text': 'said', 'start': 8.279, 'end': 8.46}, {'text': 'you', 'start': 8.519, 'end': 8.6}, {'text': 'know', 'start': 8.619, 'end': 8.739}, {'text': 'the', 'start': 8.8, 'end': 8.88}, {'text': 'look', 'start': 8.92, 'end': 9.079}, {'text': 'you', 'start': 9.119, 'end': 9.259}, {'text': 'want', 'start': 9.279, 'end': 9.619}, {'text': 'but', 'start': 9.779, 'end': 9.88}, {'text': "don't", 'start': 9.92, 'end': 10.1}, {'text': 'have', 'start': 10.159, 'end': 10.3}, {'text': 'the', 'start': 10.3, 'end': 10.42}, {'text': 'editing', 'start': 10.5, 'end': 10.779}, {'text': 'skills', 'start': 10.86, 'end': 11.139}, {'text': 'to', 'start': 11.159, 'end': 11.239}, {'text': 'get', 'start': 11.279, 'end': 11.439}, {'text': 'there.', 'start': 11.46, 'end': 12.239}, {'text': 'So', 'start': 12.3, 'end': 12.38}, {'text': 'we', 'start': 12.399, 'end': 12.519}, {'text': 'built', 'start': 12.539, 'end': 12.759}, {'text': 'Editor', 'start': 12.84, 'end': 13.119}, {'text': 'Agent.', 'start': 13.239, 'end': 13.84}];
(function () {
const TRANSCRIPT = [
{ text: "We", start: 0.14, end: 0.239 },
{ text: "asked", start: 0.28, end: 0.459 },
{ text: "what", start: 0.5, end: 0.619 },
{ text: "you", start: 0.659, end: 0.779 },
{ text: "needed.", start: 0.8, end: 1.179 },
{ text: "Forty-seven", start: 1.199, end: 1.619 },
{ text: "percent", start: 1.699, end: 1.96 },
{ text: "of", start: 1.979, end: 2.059 },
{ text: "you", start: 2.099, end: 2.299 },
{ text: "said", start: 2.319, end: 2.499 },
{ text: "motion", start: 2.559, end: 2.839 },
{ text: "graphics,", start: 2.899, end: 3.759 },
{ text: "sixty-two", start: 3.799, end: 4.159 },
{ text: "percent", start: 4.239, end: 4.559 },
{ text: "said", start: 4.639, end: 4.799 },
{ text: "static", start: 4.859, end: 5.199 },
{ text: "content", start: 5.239, end: 5.639 },
{ text: "was", start: 5.679, end: 5.779 },
{ text: "costing", start: 5.859, end: 6.219 },
{ text: "you", start: 6.259, end: 6.339 },
{ text: "attention,", start: 6.379, end: 7.299 },
{ text: "and", start: 7.319, end: 7.439 },
{ text: "three", start: 7.48, end: 7.599 },
{ text: "out", start: 7.679, end: 7.779 },
{ text: "of", start: 7.799, end: 7.879 },
{ text: "four", start: 7.94, end: 8.139 },
{ text: "said", start: 8.279, end: 8.46 },
{ text: "you", start: 8.519, end: 8.6 },
{ text: "know", start: 8.619, end: 8.739 },
{ text: "the", start: 8.8, end: 8.88 },
{ text: "look", start: 8.92, end: 9.079 },
{ text: "you", start: 9.119, end: 9.259 },
{ text: "want", start: 9.279, end: 9.619 },
{ text: "but", start: 9.779, end: 9.88 },
{ text: "don't", start: 9.92, end: 10.1 },
{ text: "have", start: 10.159, end: 10.3 },
{ text: "the", start: 10.3, end: 10.42 },
{ text: "editing", start: 10.5, end: 10.779 },
{ text: "skills", start: 10.86, end: 11.139 },
{ text: "to", start: 11.159, end: 11.239 },
{ text: "get", start: 11.279, end: 11.439 },
{ text: "there.", start: 11.46, end: 12.239 },
{ text: "So", start: 12.3, end: 12.38 },
{ text: "we", start: 12.399, end: 12.519 },
{ text: "built", start: 12.539, end: 12.759 },
{ text: "Editor", start: 12.84, end: 13.119 },
{ text: "Agent.", start: 13.239, end: 13.84 },
];
const groups = [
{ text: "We asked what you needed.", start: 0.14, end: 1.179 },
{ text: "Forty-seven percent of you said motion graphics,", start: 1.199, end: 3.759 },
{ text: "sixty-two percent said static content was costing you attention,", start: 3.799, end: 7.299 },
{ text: "and three out of four said you know the look you want", start: 7.319, end: 9.619 },
{
text: "sixty-two percent said static content was costing you attention,",
start: 3.799,
end: 7.299,
},
{
text: "and three out of four said you know the look you want",
start: 7.319,
end: 9.619,
},
{ text: "but don't have the editing skills to get there.", start: 9.779, end: 12.239 },
{ text: "So we built Editor Agent.", start: 12.3, end: 13.84 }
{ text: "So we built Editor Agent.", start: 12.3, end: 13.84 },
];
const container = document.querySelector('[data-composition-id="captions"] .captions-container');
const container = document.querySelector(
'[data-composition-id="captions"] .captions-container',
);
const tl = gsap.timeline({ paused: true });
// Add background "rails" for Tschichold aesthetic - reduced to 2-3 strategic lines
const railPositions = [
{ type: 'h', pos: '30%' },
{ type: 'h', pos: '70%' },
{ type: 'v', pos: '25%' }
{ type: "h", pos: "30%" },
{ type: "h", pos: "70%" },
{ type: "v", pos: "25%" },
];
railPositions.forEach(rail => {
const el = document.createElement('div');
railPositions.forEach((rail) => {
const el = document.createElement("div");
el.className = `rail rail-${rail.type}`;
if (rail.type === 'h') {
if (rail.type === "h") {
el.style.top = rail.pos;
} else {
el.style.left = rail.pos;
@@ -119,20 +178,37 @@
container.appendChild(el);
});
const keywords = ["asked", "needed", "forty-seven", "percent", "motion", "graphics", "sixty-two", "static", "content", "attention", "three", "four", "editing", "skills", "editor", "agent"];
const keywords = [
"asked",
"needed",
"forty-seven",
"percent",
"motion",
"graphics",
"sixty-two",
"static",
"content",
"attention",
"three",
"four",
"editing",
"skills",
"editor",
"agent",
];
groups.forEach((group, index) => {
const groupEl = document.createElement('div');
groupEl.className = 'caption-group';
groupEl.id = 'group-' + index;
const words = group.text.split(' ');
words.forEach(wordText => {
const span = document.createElement('span');
span.className = 'word';
const cleanWord = wordText.toLowerCase().replace(/[^\w]/g, '');
const groupEl = document.createElement("div");
groupEl.className = "caption-group";
groupEl.id = "group-" + index;
const words = group.text.split(" ");
words.forEach((wordText) => {
const span = document.createElement("span");
span.className = "word";
const cleanWord = wordText.toLowerCase().replace(/[^\w]/g, "");
if (keywords.includes(cleanWord)) {
span.classList.add('bold');
span.classList.add("bold");
}
span.textContent = wordText;
groupEl.appendChild(span);
@@ -140,45 +216,61 @@
container.appendChild(groupEl);
const groupWords = groupEl.querySelectorAll('.word');
const groupWords = groupEl.querySelectorAll(".word");
// Entrance
tl.set(groupEl, { visibility: 'visible' }, group.start);
tl.set(groupEl, { visibility: "visible" }, group.start);
tl.to(groupEl, { opacity: 1, duration: 0.1 }, group.start);
// Words slide into alignment along "rails"
tl.from(groupWords, {
x: (i) => (i % 2 === 0 ? -150 : 150),
opacity: 0,
duration: 0.8,
stagger: 0.04,
ease: "power4.out"
}, group.start);
tl.from(
groupWords,
{
x: (i) => (i % 2 === 0 ? -150 : 150),
opacity: 0,
duration: 0.8,
stagger: 0.04,
ease: "power4.out",
},
group.start,
);
// Exit
const exitTime = group.end;
tl.to(groupEl, {
opacity: 0,
duration: 0.2,
ease: "power2.in"
}, exitTime);
tl.set(groupEl, { visibility: 'hidden' }, exitTime + 0.2);
tl.to(
groupEl,
{
opacity: 0,
duration: 0.2,
ease: "power2.in",
},
exitTime,
);
tl.set(groupEl, { visibility: "hidden" }, exitTime + 0.2);
});
// Ambient motion for the rails
tl.to('.rail-h', {
scaleX: 0.9,
opacity: 0.03,
duration: 14,
ease: "none"
}, 0);
tl.to('.rail-v', {
scaleY: 0.9,
opacity: 0.03,
duration: 14,
ease: "none"
}, 0);
tl.to(
".rail-h",
{
scaleX: 0.9,
opacity: 0.03,
duration: 14,
ease: "none",
},
0,
);
tl.to(
".rail-v",
{
scaleY: 0.9,
opacity: 0.03,
duration: 14,
ease: "none",
},
0,
);
window.__timelines["captions"] = tl;
})();
@@ -11,7 +11,7 @@
<div class="stat-number">75%</div>
<div class="stat-fraction">(3 out of 4)</div>
</div>
<div class="text-container">
<div class="line line-1">LACK</div>
<div class="line line-2">THE ESSENTIAL</div>
@@ -29,7 +29,7 @@
[data-composition-id="hero-moment"] {
background-color: transparent;
color: #000000;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
overflow: hidden;
display: flex;
justify-content: center;
@@ -66,9 +66,9 @@
height: 200%;
top: -50%;
left: -50%;
background-image:
linear-gradient(to right, rgba(0,0,0,0.05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(0,0,0,0.05) 1px, transparent 1px);
background-image:
linear-gradient(to right, rgba(0, 0, 0, 0.05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(0, 0, 0, 0.05) 1px, transparent 1px);
background-size: 100px 100px;
transform: rotate(-15deg);
}
@@ -77,7 +77,7 @@
position: absolute;
width: 800px;
height: 800px;
border: 2px solid #BE1E2D;
border: 2px solid #be1e2d;
border-radius: 50%;
top: 50%;
left: 50%;
@@ -108,7 +108,7 @@
font-size: 280px; /* Reduced massiveness for better hierarchy */
font-weight: 300; /* Slightly more weight for legibility */
line-height: 0.8;
color: #BE1E2D;
color: #be1e2d;
letter-spacing: -10px;
opacity: 0;
}
@@ -143,7 +143,7 @@
[data-composition-id="hero-moment"] .line-2 {
font-size: 60px;
font-weight: 400;
color: #BE1E2D;
color: #be1e2d;
}
[data-composition-id="hero-moment"] .geometric-elements {
@@ -179,7 +179,7 @@
position: absolute;
width: 60px;
height: 60px;
background-color: #BE1E2D;
background-color: #be1e2d;
top: 43.5%;
left: 47.5%;
transform: scale(0);
@@ -188,110 +188,212 @@
</style>
<script>
(function() {
const TRANSCRIPT = [{'text': 'We', 'start': 0.14, 'end': 0.239}, {'text': 'asked', 'start': 0.28, 'end': 0.459}, {'text': 'what', 'start': 0.5, 'end': 0.619}, {'text': 'you', 'start': 0.659, 'end': 0.779}, {'text': 'needed.', 'start': 0.8, 'end': 1.179}, {'text': 'Forty-seven', 'start': 1.199, 'end': 1.619}, {'text': 'percent', 'start': 1.699, 'end': 1.96}, {'text': 'of', 'start': 1.979, 'end': 2.059}, {'text': 'you', 'start': 2.099, 'end': 2.299}, {'text': 'said', 'start': 2.319, 'end': 2.499}, {'text': 'motion', 'start': 2.559, 'end': 2.839}, {'text': 'graphics,', 'start': 2.899, 'end': 3.759}, {'text': 'sixty-two', 'start': 3.799, 'end': 4.159}, {'text': 'percent', 'start': 4.239, 'end': 4.559}, {'text': 'said', 'start': 4.639, 'end': 4.799}, {'text': 'static', 'start': 4.859, 'end': 5.199}, {'text': 'content', 'start': 5.239, 'end': 5.639}, {'text': 'was', 'start': 5.679, 'end': 5.779}, {'text': 'costing', 'start': 5.859, 'end': 6.219}, {'text': 'you', 'start': 6.259, 'end': 6.339}, {'text': 'attention,', 'start': 6.379, 'end': 7.299}, {'text': 'and', 'start': 7.319, 'end': 7.439}, {'text': 'three', 'start': 7.48, 'end': 7.599}, {'text': 'out', 'start': 7.679, 'end': 7.779}, {'text': 'of', 'start': 7.799, 'end': 7.879}, {'text': 'four', 'start': 7.94, 'end': 8.139}, {'text': 'said', 'start': 8.279, 'end': 8.46}, {'text': 'you', 'start': 8.519, 'end': 8.6}, {'text': 'know', 'start': 8.619, 'end': 8.739}, {'text': 'the', 'start': 8.8, 'end': 8.88}, {'text': 'look', 'start': 8.92, 'end': 9.079}, {'text': 'you', 'start': 9.119, 'end': 9.259}, {'text': 'want', 'start': 9.279, 'end': 9.619}, {'text': 'but', 'start': 9.779, 'end': 9.88}, {'text': "don't", 'start': 9.92, 'end': 10.1}, {'text': 'have', 'start': 10.159, 'end': 10.3}, {'text': 'the', 'start': 10.3, 'end': 10.42}, {'text': 'editing', 'start': 10.5, 'end': 10.779}, {'text': 'skills', 'start': 10.86, 'end': 11.139}, {'text': 'to', 'start': 11.159, 'end': 11.239}, {'text': 'get', 'start': 11.279, 'end': 11.439}, {'text': 'there.', 'start': 11.46, 'end': 12.239}, {'text': 'So', 'start': 12.3, 'end': 12.38}, {'text': 'we', 'start': 12.399, 'end': 12.519}, {'text': 'built', 'start': 12.539, 'end': 12.759}, {'text': 'Editor', 'start': 12.84, 'end': 13.119}, {'text': 'Agent.', 'start': 13.239, 'end': 13.84}];
(function () {
const TRANSCRIPT = [
{ text: "We", start: 0.14, end: 0.239 },
{ text: "asked", start: 0.28, end: 0.459 },
{ text: "what", start: 0.5, end: 0.619 },
{ text: "you", start: 0.659, end: 0.779 },
{ text: "needed.", start: 0.8, end: 1.179 },
{ text: "Forty-seven", start: 1.199, end: 1.619 },
{ text: "percent", start: 1.699, end: 1.96 },
{ text: "of", start: 1.979, end: 2.059 },
{ text: "you", start: 2.099, end: 2.299 },
{ text: "said", start: 2.319, end: 2.499 },
{ text: "motion", start: 2.559, end: 2.839 },
{ text: "graphics,", start: 2.899, end: 3.759 },
{ text: "sixty-two", start: 3.799, end: 4.159 },
{ text: "percent", start: 4.239, end: 4.559 },
{ text: "said", start: 4.639, end: 4.799 },
{ text: "static", start: 4.859, end: 5.199 },
{ text: "content", start: 5.239, end: 5.639 },
{ text: "was", start: 5.679, end: 5.779 },
{ text: "costing", start: 5.859, end: 6.219 },
{ text: "you", start: 6.259, end: 6.339 },
{ text: "attention,", start: 6.379, end: 7.299 },
{ text: "and", start: 7.319, end: 7.439 },
{ text: "three", start: 7.48, end: 7.599 },
{ text: "out", start: 7.679, end: 7.779 },
{ text: "of", start: 7.799, end: 7.879 },
{ text: "four", start: 7.94, end: 8.139 },
{ text: "said", start: 8.279, end: 8.46 },
{ text: "you", start: 8.519, end: 8.6 },
{ text: "know", start: 8.619, end: 8.739 },
{ text: "the", start: 8.8, end: 8.88 },
{ text: "look", start: 8.92, end: 9.079 },
{ text: "you", start: 9.119, end: 9.259 },
{ text: "want", start: 9.279, end: 9.619 },
{ text: "but", start: 9.779, end: 9.88 },
{ text: "don't", start: 9.92, end: 10.1 },
{ text: "have", start: 10.159, end: 10.3 },
{ text: "the", start: 10.3, end: 10.42 },
{ text: "editing", start: 10.5, end: 10.779 },
{ text: "skills", start: 10.86, end: 11.139 },
{ text: "to", start: 11.159, end: 11.239 },
{ text: "get", start: 11.279, end: 11.439 },
{ text: "there.", start: 11.46, end: 12.239 },
{ text: "So", start: 12.3, end: 12.38 },
{ text: "we", start: 12.399, end: 12.519 },
{ text: "built", start: 12.539, end: 12.759 },
{ text: "Editor", start: 12.84, end: 13.119 },
{ text: "Agent.", start: 13.239, end: 13.84 },
];
const tl = gsap.timeline({ paused: true });
// Helper to find word timing
function getWordTime(word) {
const found = TRANSCRIPT.find(w => w.text.toLowerCase().replace(/[^\w]/g, '') === word.toLowerCase());
const found = TRANSCRIPT.find(
(w) => w.text.toLowerCase().replace(/[^\w]/g, "") === word.toLowerCase(),
);
return found ? found.start : 0;
}
// 1. Entrance (Starts at 7.319s)
tl.to('[data-composition-id="hero-moment"] .accent-circle', {
opacity: 0.2,
scale: 1.2,
duration: 1,
ease: 'power2.out'
}, 7.319);
tl.to(
'[data-composition-id="hero-moment"] .accent-circle',
{
opacity: 0.2,
scale: 1.2,
duration: 1,
ease: "power2.out",
},
7.319,
);
tl.to('[data-composition-id="hero-moment"] .rule-line.horizontal', {
width: '100%',
opacity: 0.3,
duration: 0.8,
ease: 'expo.out'
}, 7.4);
tl.to(
'[data-composition-id="hero-moment"] .rule-line.horizontal',
{
width: "100%",
opacity: 0.3,
duration: 0.8,
ease: "expo.out",
},
7.4,
);
tl.to('[data-composition-id="hero-moment"] .rule-line.vertical', {
height: '100%',
opacity: 0.3,
duration: 0.8,
ease: 'expo.out'
}, 7.5);
tl.to(
'[data-composition-id="hero-moment"] .rule-line.vertical',
{
height: "100%",
opacity: 0.3,
duration: 0.8,
ease: "expo.out",
},
7.5,
);
tl.to('[data-composition-id="hero-moment"] .square-accent', {
scale: 1,
opacity: 1,
duration: 0.5,
ease: 'back.out(1.7)'
}, 7.8);
tl.to(
'[data-composition-id="hero-moment"] .square-accent',
{
scale: 1,
opacity: 1,
duration: 0.5,
ease: "back.out(1.7)",
},
7.8,
);
// 2. Kinetic Typography synced to transcript
// "75%" (three out of four)
const timeThree = getWordTime('three');
tl.to('[data-composition-id="hero-moment"] .stat-number', {
opacity: 1,
duration: 0.8,
ease: 'power4.out'
}, timeThree);
const timeThree = getWordTime("three");
tl.to(
'[data-composition-id="hero-moment"] .stat-number',
{
opacity: 1,
duration: 0.8,
ease: "power4.out",
},
timeThree,
);
tl.to('[data-composition-id="hero-moment"] .stat-fraction', {
opacity: 0.8,
duration: 0.8,
ease: 'power2.out'
}, timeThree + 0.2);
tl.to(
'[data-composition-id="hero-moment"] .stat-fraction',
{
opacity: 0.8,
duration: 0.8,
ease: "power2.out",
},
timeThree + 0.2,
);
// "lack"
const timeSkills = getWordTime('skills');
tl.to('[data-composition-id="hero-moment"] .line-1', {
opacity: 1,
duration: 0.6,
ease: 'back.out(1.2)'
}, timeSkills - 0.4);
const timeSkills = getWordTime("skills");
tl.to(
'[data-composition-id="hero-moment"] .line-1',
{
opacity: 1,
duration: 0.6,
ease: "back.out(1.2)",
},
timeSkills - 0.4,
);
// "essential"
tl.to('[data-composition-id="hero-moment"] .line-2', {
opacity: 1,
duration: 0.6,
ease: 'back.out(1.2)'
}, timeSkills - 0.2);
tl.to(
'[data-composition-id="hero-moment"] .line-2',
{
opacity: 1,
duration: 0.6,
ease: "back.out(1.2)",
},
timeSkills - 0.2,
);
// "skills"
tl.to('[data-composition-id="hero-moment"] .line-3', {
opacity: 1,
duration: 0.6,
ease: 'back.out(1.2)'
}, timeSkills);
tl.to(
'[data-composition-id="hero-moment"] .line-3',
{
opacity: 1,
duration: 0.6,
ease: "back.out(1.2)",
},
timeSkills,
);
// 3. Ambient Motion (Continuous)
tl.to('[data-composition-id="hero-moment"] .grid-lines', {
x: '+=50',
y: '+=50',
duration: 14,
ease: 'none'
}, 0);
tl.to(
'[data-composition-id="hero-moment"] .grid-lines',
{
x: "+=50",
y: "+=50",
duration: 14,
ease: "none",
},
0,
);
tl.to('[data-composition-id="hero-moment"] .accent-circle', {
scale: 1.3,
duration: 14,
ease: 'sine.inOut'
}, 0);
tl.to(
'[data-composition-id="hero-moment"] .accent-circle',
{
scale: 1.3,
duration: 14,
ease: "sine.inOut",
},
0,
);
// 4. Exit (Starts at 12.239s)
tl.to('[data-composition-id="hero-moment"] .content-layer, [data-composition-id="hero-moment"] .geometric-elements', {
opacity: 0,
y: 50,
duration: 0.6,
ease: 'power3.in'
}, 12.239);
tl.to(
'[data-composition-id="hero-moment"] .content-layer, [data-composition-id="hero-moment"] .geometric-elements',
{
opacity: 0,
y: 50,
duration: 0.6,
ease: "power3.in",
},
12.239,
);
tl.to('[data-composition-id="hero-moment"] .accent-circle', {
scale: 2,
opacity: 0,
duration: 0.8,
ease: 'power2.in'
}, 12.239);
tl.to(
'[data-composition-id="hero-moment"] .accent-circle',
{
scale: 2,
opacity: 0,
duration: 0.8,
ease: "power2.in",
},
12.239,
);
window.__timelines["hero-moment"] = tl;
})();
@@ -1,5 +1,10 @@
<template id="mograph-overlays-template">
<div data-composition-id="mograph-overlays" data-width="1080" data-height="1920" data-duration="14">
<div
data-composition-id="mograph-overlays"
data-width="1080"
data-height="1920"
data-duration="14"
>
<div id="mograph-container">
<!-- Ambient Elements -->
<div class="diagonal-line line-1"></div>
@@ -8,7 +13,7 @@
<div class="marker marker-tr"></div>
<div class="marker marker-bl"></div>
<div class="marker marker-br"></div>
<!-- Alignment Indicators -->
<div class="alignment-h"></div>
<div class="alignment-v"></div>
@@ -22,7 +27,7 @@
width: 1080px;
height: 1920px;
overflow: hidden;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #000000;
}
@@ -35,7 +40,7 @@
/* Diagonal Lines - Modernist Red */
[data-composition-id="mograph-overlays"] .diagonal-line {
position: absolute;
background: #BE1E2D;
background: #be1e2d;
height: 1px;
opacity: 0.2;
}
@@ -63,10 +68,30 @@
opacity: 0.4;
}
[data-composition-id="mograph-overlays"] .marker-tl { top: 60px; left: 60px; border-right: 0; border-bottom: 0; }
[data-composition-id="mograph-overlays"] .marker-tr { top: 60px; right: 60px; border-left: 0; border-bottom: 0; }
[data-composition-id="mograph-overlays"] .marker-bl { bottom: 60px; left: 60px; border-right: 0; border-top: 0; }
[data-composition-id="mograph-overlays"] .marker-br { bottom: 60px; right: 60px; border-left: 0; border-top: 0; }
[data-composition-id="mograph-overlays"] .marker-tl {
top: 60px;
left: 60px;
border-right: 0;
border-bottom: 0;
}
[data-composition-id="mograph-overlays"] .marker-tr {
top: 60px;
right: 60px;
border-left: 0;
border-bottom: 0;
}
[data-composition-id="mograph-overlays"] .marker-bl {
bottom: 60px;
left: 60px;
border-right: 0;
border-top: 0;
}
[data-composition-id="mograph-overlays"] .marker-br {
bottom: 60px;
right: 60px;
border-left: 0;
border-top: 0;
}
/* Alignment Indicators - Subtle Grid */
[data-composition-id="mograph-overlays"] .alignment-h {
@@ -75,7 +100,7 @@
left: 80px;
right: 80px;
height: 1px;
background: rgba(0,0,0,0.05);
background: rgba(0, 0, 0, 0.05);
}
[data-composition-id="mograph-overlays"] .alignment-v {
@@ -84,7 +109,7 @@
top: 80px;
bottom: 80px;
width: 1px;
background: rgba(0,0,0,0.05);
background: rgba(0, 0, 0, 0.05);
}
/* Dynamic Graphic - Modernist Museum Style */
@@ -110,7 +135,7 @@
font-weight: 500;
letter-spacing: 6px;
margin-top: 15px;
color: #BE1E2D; /* Accent color for label */
color: #be1e2d; /* Accent color for label */
text-transform: uppercase;
}
@@ -123,24 +148,76 @@
</style>
<script>
(function() {
const TRANSCRIPT = [{'text': 'We', 'start': 0.14, 'end': 0.239}, {'text': 'asked', 'start': 0.28, 'end': 0.459}, {'text': 'what', 'start': 0.5, 'end': 0.619}, {'text': 'you', 'start': 0.659, 'end': 0.779}, {'text': 'needed.', 'start': 0.8, 'end': 1.179}, {'text': 'Forty-seven', 'start': 1.199, 'end': 1.619}, {'text': 'percent', 'start': 1.699, 'end': 1.96}, {'text': 'of', 'start': 1.979, 'end': 2.059}, {'text': 'you', 'start': 2.099, 'end': 2.299}, {'text': 'said', 'start': 2.319, 'end': 2.499}, {'text': 'motion', 'start': 2.559, 'end': 2.839}, {'text': 'graphics,', 'start': 2.899, 'end': 3.759}, {'text': 'sixty-two', 'start': 3.799, 'end': 4.159}, {'text': 'percent', 'start': 4.239, 'end': 4.559}, {'text': 'said', 'start': 4.639, 'end': 4.799}, {'text': 'static', 'start': 4.859, 'end': 5.199}, {'text': 'content', 'start': 5.239, 'end': 5.639}, {'text': 'was', 'start': 5.679, 'end': 5.779}, {'text': 'costing', 'start': 5.859, 'end': 6.219}, {'text': 'you', 'start': 6.259, 'end': 6.339}, {'text': 'attention,', 'start': 6.379, 'end': 7.299}, {'text': 'and', 'start': 7.319, 'end': 7.439}, {'text': 'three', 'start': 7.48, 'end': 7.599}, {'text': 'out', 'start': 7.679, 'end': 7.779}, {'text': 'of', 'start': 7.799, 'end': 7.879}, {'text': 'four', 'start': 7.94, 'end': 8.139}, {'text': 'said', 'start': 8.279, 'end': 8.46}, {'text': 'you', 'start': 8.519, 'end': 8.6}, {'text': 'know', 'start': 8.619, 'end': 8.739}, {'text': 'the', 'start': 8.8, 'end': 8.88}, {'text': 'look', 'start': 8.92, 'end': 9.079}, {'text': 'you', 'start': 9.119, 'end': 9.259}, {'text': 'want', 'start': 9.279, 'end': 9.619}, {'text': 'but', 'start': 9.779, 'end': 9.88}, {'text': "don't", 'start': 9.92, 'end': 10.1}, {'text': 'have', 'start': 10.159, 'end': 10.3}, {'text': 'the', 'start': 10.3, 'end': 10.42}, {'text': 'editing', 'start': 10.5, 'end': 10.779}, {'text': 'skills', 'start': 10.86, 'end': 11.139}, {'text': 'to', 'start': 11.159, 'end': 11.239}, {'text': 'get', 'start': 11.279, 'end': 11.439}, {'text': 'there.', 'start': 11.46, 'end': 12.239}, {'text': 'So', 'start': 12.3, 'end': 12.38}, {'text': 'we', 'start': 12.399, 'end': 12.519}, {'text': 'built', 'start': 12.539, 'end': 12.759}, {'text': 'Editor', 'start': 12.84, 'end': 13.119}, {'text': 'Agent.', 'start': 13.239, 'end': 13.84}];
(function () {
const TRANSCRIPT = [
{ text: "We", start: 0.14, end: 0.239 },
{ text: "asked", start: 0.28, end: 0.459 },
{ text: "what", start: 0.5, end: 0.619 },
{ text: "you", start: 0.659, end: 0.779 },
{ text: "needed.", start: 0.8, end: 1.179 },
{ text: "Forty-seven", start: 1.199, end: 1.619 },
{ text: "percent", start: 1.699, end: 1.96 },
{ text: "of", start: 1.979, end: 2.059 },
{ text: "you", start: 2.099, end: 2.299 },
{ text: "said", start: 2.319, end: 2.499 },
{ text: "motion", start: 2.559, end: 2.839 },
{ text: "graphics,", start: 2.899, end: 3.759 },
{ text: "sixty-two", start: 3.799, end: 4.159 },
{ text: "percent", start: 4.239, end: 4.559 },
{ text: "said", start: 4.639, end: 4.799 },
{ text: "static", start: 4.859, end: 5.199 },
{ text: "content", start: 5.239, end: 5.639 },
{ text: "was", start: 5.679, end: 5.779 },
{ text: "costing", start: 5.859, end: 6.219 },
{ text: "you", start: 6.259, end: 6.339 },
{ text: "attention,", start: 6.379, end: 7.299 },
{ text: "and", start: 7.319, end: 7.439 },
{ text: "three", start: 7.48, end: 7.599 },
{ text: "out", start: 7.679, end: 7.779 },
{ text: "of", start: 7.799, end: 7.879 },
{ text: "four", start: 7.94, end: 8.139 },
{ text: "said", start: 8.279, end: 8.46 },
{ text: "you", start: 8.519, end: 8.6 },
{ text: "know", start: 8.619, end: 8.739 },
{ text: "the", start: 8.8, end: 8.88 },
{ text: "look", start: 8.92, end: 9.079 },
{ text: "you", start: 9.119, end: 9.259 },
{ text: "want", start: 9.279, end: 9.619 },
{ text: "but", start: 9.779, end: 9.88 },
{ text: "don't", start: 9.92, end: 10.1 },
{ text: "have", start: 10.159, end: 10.3 },
{ text: "the", start: 10.3, end: 10.42 },
{ text: "editing", start: 10.5, end: 10.779 },
{ text: "skills", start: 10.86, end: 11.139 },
{ text: "to", start: 11.159, end: 11.239 },
{ text: "get", start: 11.279, end: 11.439 },
{ text: "there.", start: 11.46, end: 12.239 },
{ text: "So", start: 12.3, end: 12.38 },
{ text: "we", start: 12.399, end: 12.519 },
{ text: "built", start: 12.539, end: 12.759 },
{ text: "Editor", start: 12.84, end: 13.119 },
{ text: "Agent.", start: 13.239, end: 13.84 },
];
const tl = gsap.timeline({ paused: true });
// Face Avoidance Area: x:300-776, y:320-796
// Safe zones: Right side (x > 800), Top (y < 300), Bottom (y > 800)
// 1. Ambient Motion (Continuous & Subtle)
tl.to('.line-1', { x: 30, y: 10, duration: 14, ease: 'none' }, 0);
tl.to('.line-2', { x: -30, y: -10, duration: 14, ease: 'none' }, 0);
tl.from('.marker', {
scale: 0.9,
opacity: 0,
duration: 1.5,
stagger: 0.3,
ease: 'power2.out'
}, 0);
tl.to(".line-1", { x: 30, y: 10, duration: 14, ease: "none" }, 0);
tl.to(".line-2", { x: -30, y: -10, duration: 14, ease: "none" }, 0);
tl.from(
".marker",
{
scale: 0.9,
opacity: 0,
duration: 1.5,
stagger: 0.3,
ease: "power2.out",
},
0,
);
// 2. Transcript-Synced Graphics
// Updated content based on design review
@@ -148,22 +225,24 @@
{ word: "47%", label: "USER SURVEY" },
{ word: "static", label: "CONTENT ENGAGEMENT" },
{ word: "editing", label: "TECHNICAL SKILLS" },
{ word: "Editor", label: "SYSTEM ARCHITECTURE" }
{ word: "Editor", label: "SYSTEM ARCHITECTURE" },
];
triggerWords.forEach((trigger, index) => {
const wordData = TRANSCRIPT.find(w => w.text.toLowerCase().includes(trigger.word.toLowerCase()));
const wordData = TRANSCRIPT.find((w) =>
w.text.toLowerCase().includes(trigger.word.toLowerCase()),
);
if (wordData) {
const startTime = wordData.start;
const duration = 3.0;
// Deterministic positioning outside face area (Vertical Safe Zones)
// Face: x:300-776, y:320-796 (approx in vertical)
const positions = [
{ x: 50, y: 1500 }, // Bottom Left
{ x: 50, y: 1500 }, // Bottom Left
{ x: 600, y: 1600 }, // Bottom Right
{ x: 100, y: 100 }, // Top Left
{ x: 500, y: 50 } // Top Right
{ x: 100, y: 100 }, // Top Left
{ x: 500, y: 50 }, // Top Right
];
const pos = positions[index % positions.length];
@@ -176,48 +255,70 @@
<div class="graphic-line"></div>
</div>
`;
document.getElementById('mograph-container').insertAdjacentHTML('beforeend', graphicHtml);
document
.getElementById("mograph-container")
.insertAdjacentHTML("beforeend", graphicHtml);
const graphicSelector = `#${graphicId}`;
// Entrance - Clean and Sophisticated
tl.to(graphicSelector, {
opacity: 1,
duration: 1.0,
ease: 'power3.out'
}, startTime);
tl.from(`${graphicSelector} .graphic-value`, {
x: -20,
opacity: 0,
duration: 1.2,
ease: 'power4.out'
}, startTime + 0.1);
tl.to(`${graphicSelector} .graphic-line`, {
width: 250,
duration: 1.5,
ease: 'expo.out'
}, startTime + 0.4);
tl.to(
graphicSelector,
{
opacity: 1,
duration: 1.0,
ease: "power3.out",
},
startTime,
);
tl.from(
`${graphicSelector} .graphic-value`,
{
x: -20,
opacity: 0,
duration: 1.2,
ease: "power4.out",
},
startTime + 0.1,
);
tl.to(
`${graphicSelector} .graphic-line`,
{
width: 250,
duration: 1.5,
ease: "expo.out",
},
startTime + 0.4,
);
// Exit - Smooth Fade
tl.to(graphicSelector, {
opacity: 0,
x: 20,
duration: 0.8,
ease: 'power2.in'
}, startTime + duration);
tl.to(
graphicSelector,
{
opacity: 0,
x: 20,
duration: 0.8,
ease: "power2.in",
},
startTime + duration,
);
}
});
// 3. Subtle Grid/Alignment pulses
tl.to('.alignment-h, .alignment-v', {
opacity: 0.2,
duration: 0.5,
repeat: 3,
yoyo: true,
ease: 'power1.inOut'
}, 1);
tl.to(
".alignment-h, .alignment-v",
{
opacity: 0.2,
duration: 0.5,
repeat: 3,
yoyo: true,
ease: "power1.inOut",
},
1,
);
window.__timelines["mograph-overlays"] = tl;
})();
@@ -1,6 +1,7 @@
# HyperFrames Design Review
## First Impression
This looks like a Bauhaus-inspired museum exhibit had a head-on collision with a TikTok ad. Its trying to be Jan Tschichold, but its currently closer to "I just discovered the Helvetica font and the color red."
---
@@ -10,18 +11,21 @@ This looks like a Bauhaus-inspired museum exhibit had a head-on collision with a
Issues that make this look unprofessional or straight-up ugly. These MUST be fixed.
### The "Floating Head" Problem
**Where:** `compositions/aroll.html`
**What's wrong:** The A-Roll video is set to `object-fit: cover` and fills the entire 1080x1920 frame. While bold, it completely ignores the "safe zones" for the face. The `mograph_overlays.html` then proceeds to slap text directly over where the speaker's face likely is.
**Why it matters:** You're literally covering the speaker's mouth or eyes with "USER SURVEY" and "47%". It looks like a mistake, not a design choice.
**Fix it:** Scale the A-Roll video down or use a mask that respects the rule of thirds. If you're going full-screen, your overlays need to be pushed to the extreme margins.
### Caption Chaos
**Where:** `compositions/captions.html`
**What's wrong:** You have words jumping from `font-size: 50px` to `140px` with a `line-height: 0.9`. In a 9:16 portrait format, this is going to cause massive, ugly overlaps and erratic wrapping.
**Why it matters:** Readability is the first casualty of "cool" design. If the viewer has to squint or decode which word comes next because they're stacked like a game of Tetris, you've failed.
**Fix it:** Standardize the scale variance. 50px to 140px is too wide a gap. Try 80px to 120px. Increase the `line-height` to at least `1.1` to give the descenders some breathing room.
### The "Dead" Background
**Where:** `compositions/background.html`
**What's wrong:** A `#FAF5E8` (off-white) background with a `0.05` opacity noise filter is basically just a flat, boring beige on most mobile screens. The grid lines are too thin (`1px`, `2px`) to feel intentional; they just look like screen artifacts.
**Why it matters:** It lacks depth. It feels like a default template rather than a premium "New Typography" aesthetic.
@@ -34,11 +38,13 @@ Issues that make this look unprofessional or straight-up ugly. These MUST be fix
Things that aren't broken but are boring, lazy, or could be significantly better.
### Robotic Motion
**Where:** `compositions/mograph_overlays.html`
**The problem:** The diagonal lines and markers just "drift" linearly. Its the most basic GSAP animation possible.
**Make it better:** Add some "snap" to the entrance. Use `expo.out` or `back.out` for the markers. Give the lines a slight pulse in opacity or thickness to make them feel like they're reacting to the audio, not just floating in space.
### Hero Moment Hierarchy
**Where:** `compositions/hero_moment.html`
**The problem:** The "75%" is `280px` while the supporting text is `120px`. Its a bit of a "shouting match" between elements.
**Make it better:** Lean into the Tschichold asymmetry. Move the "75%" off-center. Use a much heavier weight for the number and a much lighter, tracked-out weight for the text. Contrast is your friend; stop making everything "big."
@@ -1,86 +1,106 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Jan Tschichold Typography Video</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<style>
body, html {
margin: 0;
padding: 0;
width: 1080px;
height: 1920px;
overflow: hidden;
background-color: #FAF5E8;
}
#master-composition {
width: 1080px;
height: 1920px;
position: relative;
z-index: 0;
}
#bg-comp { z-index: 1; }
#aroll-comp { z-index: 2; }
#hero-comp { z-index: 3; }
#mograph-comp { z-index: 4; }
#captions-comp { z-index: 5; }
body,
html {
margin: 0;
padding: 0;
width: 1080px;
height: 1920px;
overflow: hidden;
background-color: #faf5e8;
}
#master-composition {
width: 1080px;
height: 1920px;
position: relative;
z-index: 0;
}
#bg-comp {
z-index: 1;
}
#aroll-comp {
z-index: 2;
}
#hero-comp {
z-index: 3;
}
#mograph-comp {
z-index: 4;
}
#captions-comp {
z-index: 5;
}
</style>
</head>
<body>
<div id="master-composition" data-composition-id="master" data-width="1080" data-height="1920" data-duration="14">
<!-- Background Layer -->
<div id="bg-comp"
data-composition-id="background"
data-composition-src="compositions/background.html"
data-start="0"
data-duration="14"
data-track-index="0">
</div>
</head>
<body>
<div
id="master-composition"
data-composition-id="master"
data-width="1080"
data-height="1920"
data-duration="14"
>
<!-- Background Layer -->
<div
id="bg-comp"
data-composition-id="background"
data-composition-src="compositions/background.html"
data-start="0"
data-duration="14"
data-track-index="0"
></div>
<!-- A-Roll Video Layer -->
<div id="aroll-comp"
data-composition-id="aroll"
data-composition-src="compositions/aroll.html"
data-start="0"
data-duration="14"
data-track-index="1">
</div>
<!-- A-Roll Video Layer -->
<div
id="aroll-comp"
data-composition-id="aroll"
data-composition-src="compositions/aroll.html"
data-start="0"
data-duration="14"
data-track-index="1"
></div>
<!-- Hero Moment (Full Canvas) -->
<div id="hero-comp"
data-composition-id="hero-moment"
data-composition-src="compositions/hero_moment.html"
data-start="0"
data-duration="14"
data-track-index="2">
</div>
<!-- Hero Moment (Full Canvas) -->
<div
id="hero-comp"
data-composition-id="hero-moment"
data-composition-src="compositions/hero_moment.html"
data-start="0"
data-duration="14"
data-track-index="2"
></div>
<!-- Motion Graphic Overlays -->
<div id="mograph-comp"
data-composition-id="mograph-overlays"
data-composition-src="compositions/mograph_overlays.html"
data-start="0"
data-duration="14"
data-track-index="3">
</div>
<!-- Captions Layer -->
<div id="captions-comp"
data-composition-id="captions"
data-composition-src="compositions/captions.html"
data-start="0"
data-duration="14"
data-track-index="4">
</div>
<!-- Motion Graphic Overlays -->
<div
id="mograph-comp"
data-composition-id="mograph-overlays"
data-composition-src="compositions/mograph_overlays.html"
data-start="0"
data-duration="14"
data-track-index="3"
></div>
<!-- Captions Layer -->
<div
id="captions-comp"
data-composition-id="captions"
data-composition-src="compositions/captions.html"
data-start="0"
data-duration="14"
data-track-index="4"
></div>
</div>
<script>
window.__timelines = {};
const masterTL = gsap.timeline({ paused: true });
window.__timelines["master"] = masterTL;
window.__timelines = {};
const masterTL = gsap.timeline({ paused: true });
window.__timelines["master"] = masterTL;
</script>
</body>
</body>
</html>