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: 3
- Critical issues: 0
- Overall compliance status: PASS
## Critical Issues
None. The compositions follow the deterministic requirements and essential timeline registration rules.
## 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`
@@ -28,9 +31,11 @@ None. The compositions follow the deterministic requirements and essential timel
## File Reviews
### index.html
**Status**: COMPLIANT
**Observations**:
- Correctly defines the root composition `main-video`.
- Uses `data-width="1920"` and `data-height="1080"` as requested for Landscape orientation.
- Properly registers `window.__timelines["main-video"]`.
@@ -39,9 +44,11 @@ None. The compositions follow the deterministic requirements and essential timel
- Track assignments are clean: Track 0 (BG), Track 1 (Video), Track 2 (Graphics), Track 3 (Captions), Track 4 (Audio).
### compositions/captions.html
**Status**: COMPLIANT
**Observations**:
- Uses `<template>` tag correctly.
- Root element has `data-composition-id`, `data-width`, `data-height`, and `data-duration`.
- Script is deterministic, using a fixed `TRANSCRIPT` array.
@@ -49,9 +56,11 @@ None. The compositions follow the deterministic requirements and essential timel
- Note: The `data-composition-id` in the HTML is `captions`, and the script registers `captions`. In `index.html`, the container has `data-composition-id="captions-comp"`. The framework typically matches the registration to the ID of the element being instantiated. Since the template root has `data-composition-id="captions"`, this is the ID that should be registered.
### compositions/graphics.html
**Status**: COMPLIANT
**Observations**:
- Uses `<template>` tag correctly.
- Root element has `data-composition-id`, `data-width`, `data-height`, and `data-duration`.
- Animations are deterministic GSAP tweens.
@@ -59,5 +68,6 @@ None. The compositions follow the deterministic requirements and essential timel
- Layout is well-coordinated with the A-roll positioning defined in the master timeline.
## Recommendations
- **Consistency**: In `index.html`, the captions container uses `data-composition-id="captions-comp"`, but the template inside `captions.html` uses `data-composition-id="captions"`. While the framework handles the swap during instantiation, keeping these IDs identical (e.g., both `captions`) improves maintainability.
- **Deterministic Logic**: The use of `(function() { ... })()` in sub-compositions is a good practice for scoping.
@@ -26,8 +26,8 @@
bottom: 0;
/* No left: 50% here, we rely on the container's flex centering */
background-color: #000000; /* Dark solid background strip */
color: #FFFFFF; /* White */
font-family: 'Futura', 'DIN Alternate', 'Arial Black', sans-serif;
color: #ffffff; /* White */
font-family: "Futura", "DIN Alternate", "Arial Black", sans-serif;
font-weight: 900;
font-size: 56px;
padding: 15px 40px;
@@ -41,20 +41,71 @@
</style>
<script>
(function() {
const TRANSCRIPT = [{'text': 'We', 'start': 0.119, 'end': 0.259}, {'text': 'asked', 'start': 0.319, 'end': 0.479}, {'text': 'what', 'start': 0.519, 'end': 0.659}, {'text': 'you', 'start': 0.699, 'end': 0.819}, {'text': 'needed.', 'start': 0.859, 'end': 1.819}, {'text': 'Forty-seven', 'start': 1.86, 'end': 2.299}, {'text': 'percent', 'start': 2.399, 'end': 2.679}, {'text': 'of', 'start': 2.7, 'end': 2.799}, {'text': 'you', 'start': 2.839, 'end': 2.939}, {'text': 'said', 'start': 3.039, 'end': 3.179}, {'text': 'motion', 'start': 3.24, 'end': 3.559}, {'text': 'graphics,', 'start': 3.579, 'end': 4.599}, {'text': 'sixty-two', 'start': 4.679, 'end': 5.179}, {'text': 'percent', 'start': 5.299, 'end': 5.759}, {'text': 'said', 'start': 5.859, 'end': 5.98}, {'text': 'static', 'start': 6.079, 'end': 6.399}, {'text': 'content', 'start': 6.46, 'end': 6.879}, {'text': 'was', 'start': 6.92, 'end': 7.079}, {'text': 'costing', 'start': 7.099, 'end': 7.48}, {'text': 'you', 'start': 7.5, 'end': 7.579}, {'text': 'attention,', 'start': 7.679, 'end': 8.659}, {'text': 'and', 'start': 8.699, 'end': 8.86}, {'text': 'three', 'start': 8.88, 'end': 9.06}, {'text': 'out', 'start': 9.079, 'end': 9.18}, {'text': 'of', 'start': 9.199, 'end': 9.34}, {'text': 'four', 'start': 9.38, 'end': 9.799}, {'text': 'said', 'start': 9.84, 'end': 10.0}, {'text': 'you', 'start': 10.019, 'end': 10.159}, {'text': 'know', 'start': 10.179, 'end': 10.36}, {'text': 'the', 'start': 10.38, 'end': 10.42}, {'text': 'look', 'start': 10.519, 'end': 10.699}, {'text': 'you', 'start': 10.739, 'end': 10.859}, {'text': 'want,', 'start': 10.98, 'end': 11.34}, {'text': 'but', 'start': 11.359, 'end': 11.52}, {'text': "don't", 'start': 11.56, 'end': 11.779}, {'text': 'have', 'start': 11.819, 'end': 11.94}, {'text': 'the', 'start': 11.96, 'end': 12.06}, {'text': 'editing', 'start': 12.079, 'end': 12.4}, {'text': 'skills', 'start': 12.52, 'end': 12.859}, {'text': 'to', 'start': 12.88, 'end': 13.0}, {'text': 'get', 'start': 13.019, 'end': 13.18}, {'text': 'there.', 'start': 13.22, 'end': 14.22}, {'text': 'So', 'start': 14.239, 'end': 14.399}, {'text': 'we', 'start': 14.42, 'end': 14.52}, {'text': 'built', 'start': 14.619, 'end': 14.88}, {'text': 'Editor', 'start': 15.079, 'end': 15.42}, {'text': 'Agent.', 'start': 15.619, 'end': 16.02}];
const container = document.getElementById('captions-container');
(function () {
const TRANSCRIPT = [
{ text: "We", start: 0.119, end: 0.259 },
{ text: "asked", start: 0.319, end: 0.479 },
{ text: "what", start: 0.519, end: 0.659 },
{ text: "you", start: 0.699, end: 0.819 },
{ text: "needed.", start: 0.859, end: 1.819 },
{ text: "Forty-seven", start: 1.86, end: 2.299 },
{ text: "percent", start: 2.399, end: 2.679 },
{ text: "of", start: 2.7, end: 2.799 },
{ text: "you", start: 2.839, end: 2.939 },
{ text: "said", start: 3.039, end: 3.179 },
{ text: "motion", start: 3.24, end: 3.559 },
{ text: "graphics,", start: 3.579, end: 4.599 },
{ text: "sixty-two", start: 4.679, end: 5.179 },
{ text: "percent", start: 5.299, end: 5.759 },
{ text: "said", start: 5.859, end: 5.98 },
{ text: "static", start: 6.079, end: 6.399 },
{ text: "content", start: 6.46, end: 6.879 },
{ text: "was", start: 6.92, end: 7.079 },
{ text: "costing", start: 7.099, end: 7.48 },
{ text: "you", start: 7.5, end: 7.579 },
{ text: "attention,", start: 7.679, end: 8.659 },
{ text: "and", start: 8.699, end: 8.86 },
{ text: "three", start: 8.88, end: 9.06 },
{ text: "out", start: 9.079, end: 9.18 },
{ text: "of", start: 9.199, end: 9.34 },
{ text: "four", start: 9.38, end: 9.799 },
{ text: "said", start: 9.84, end: 10.0 },
{ text: "you", start: 10.019, end: 10.159 },
{ text: "know", start: 10.179, end: 10.36 },
{ text: "the", start: 10.38, end: 10.42 },
{ text: "look", start: 10.519, end: 10.699 },
{ text: "you", start: 10.739, end: 10.859 },
{ text: "want,", start: 10.98, end: 11.34 },
{ text: "but", start: 11.359, end: 11.52 },
{ text: "don't", start: 11.56, end: 11.779 },
{ text: "have", start: 11.819, end: 11.94 },
{ text: "the", start: 11.96, end: 12.06 },
{ text: "editing", start: 12.079, end: 12.4 },
{ text: "skills", start: 12.52, end: 12.859 },
{ text: "to", start: 12.88, end: 13.0 },
{ text: "get", start: 13.019, end: 13.18 },
{ text: "there.", start: 13.22, end: 14.22 },
{ text: "So", start: 14.239, end: 14.399 },
{ text: "we", start: 14.42, end: 14.52 },
{ text: "built", start: 14.619, end: 14.88 },
{ text: "Editor", start: 15.079, end: 15.42 },
{ text: "Agent.", start: 15.619, end: 16.02 },
];
const container = document.getElementById("captions-container");
const tl = gsap.timeline({ paused: true });
const lines = [];
let currentLine = [];
TRANSCRIPT.forEach((word, index) => {
currentLine.push(word);
if (currentLine.length === 5 || index === TRANSCRIPT.length - 1) {
lines.push({
words: [...currentLine],
text: currentLine.map(w => w.text).join(' ').toUpperCase()
text: currentLine
.map((w) => w.text)
.join(" ")
.toUpperCase(),
});
currentLine = [];
}
@@ -63,28 +114,36 @@
lines.forEach((line, index) => {
const startTime = line.words[0].start;
const endTime = line.words[line.words.length - 1].end;
const lineEl = document.createElement('div');
lineEl.className = 'caption-line';
const lineEl = document.createElement("div");
lineEl.className = "caption-line";
lineEl.textContent = line.text;
container.appendChild(lineEl);
// Center the line element relative to the container
gsap.set(lineEl, { left: '50%', xPercent: -50 });
gsap.set(lineEl, { left: "50%", xPercent: -50 });
tl.to(lineEl, {
opacity: 1,
y: -20,
duration: 0.2,
ease: 'power2.out'
}, startTime);
tl.to(
lineEl,
{
opacity: 1,
y: -20,
duration: 0.2,
ease: "power2.out",
},
startTime,
);
tl.to(lineEl, {
opacity: 0,
y: -40,
duration: 0.1,
ease: 'power2.in'
}, endTime);
tl.to(
lineEl,
{
opacity: 0,
y: -40,
duration: 0.1,
ease: "power2.in",
},
endTime,
);
});
window.__timelines["captions"] = tl;
@@ -41,12 +41,14 @@
left: 0;
width: 1920px;
height: 1080px;
font-family: 'Futura', 'DIN Alternate', 'Arial Black', sans-serif;
font-family: "Futura", "DIN Alternate", "Arial Black", sans-serif;
overflow: hidden;
}
/* Common Styles */
.intro-container, .stat-container, .outro-container {
.intro-container,
.stat-container,
.outro-container {
position: absolute;
top: 0;
left: 0;
@@ -87,7 +89,7 @@
.intro-text {
font-size: 100px;
font-weight: 900;
color: #D0021B;
color: #d0021b;
z-index: 2;
text-align: center;
width: 1000px;
@@ -97,14 +99,14 @@
.stat-1 .vermillion-square {
width: 600px;
height: 600px;
background-color: #D0021B;
background-color: #d0021b;
position: absolute;
left: 50px;
top: 240px;
}
.stat-1 .stat-number {
color: #FFFFFF;
color: #ffffff;
position: absolute;
left: 100px;
top: 400px;
@@ -126,7 +128,7 @@
.stat-2 .white-circle {
width: 550px; /* Scaled down from 650px to avoid clipping */
height: 550px;
background-color: #D0021B; /* Vermillion background */
background-color: #d0021b; /* Vermillion background */
border-radius: 50%;
position: absolute;
right: 100px; /* Moved further right to avoid A-roll */
@@ -139,7 +141,7 @@
.stat-2 .stat-number {
color: #000000; /* Black text */
position: relative;
position: relative;
right: auto;
top: auto;
font-size: 180px; /* Slightly adjusted for better fit in circle */
@@ -165,13 +167,13 @@
}
.stat-3 .stat-number {
color: #D0021B;
color: #d0021b;
position: absolute;
top: 100px;
}
.stat-3 .stat-subtext {
color: #FFFFFF;
color: #ffffff;
top: 300px;
}
@@ -179,7 +181,7 @@
.outro-circle {
width: 900px;
height: 900px;
background-color: #D0021B;
background-color: #d0021b;
border-radius: 50%;
position: absolute;
}
@@ -195,42 +197,118 @@
</style>
<script>
(function() {
const TRANSCRIPT = [{'text': 'We', 'start': 0.119, 'end': 0.259}, {'text': 'asked', 'start': 0.319, 'end': 0.479}, {'text': 'what', 'start': 0.519, 'end': 0.659}, {'text': 'you', 'start': 0.699, 'end': 0.819}, {'text': 'needed.', 'start': 0.859, 'end': 1.819}, {'text': 'Forty-seven', 'start': 1.86, 'end': 2.299}, {'text': 'percent', 'start': 2.399, 'end': 2.679}, {'text': 'of', 'start': 2.7, 'end': 2.799}, {'text': 'you', 'start': 2.839, 'end': 2.939}, {'text': 'said', 'start': 3.039, 'end': 3.179}, {'text': 'motion', 'start': 3.24, 'end': 3.559}, {'text': 'graphics,', 'start': 3.579, 'end': 4.599}, {'text': 'sixty-two', 'start': 4.679, 'end': 5.179}, {'text': 'percent', 'start': 5.299, 'end': 5.759}, {'text': 'said', 'start': 5.859, 'end': 5.98}, {'text': 'static', 'start': 6.079, 'end': 6.399}, {'text': 'content', 'start': 6.46, 'end': 6.879}, {'text': 'was', 'start': 6.92, 'end': 7.079}, {'text': 'costing', 'start': 7.099, 'end': 7.48}, {'text': 'you', 'start': 7.5, 'end': 7.579}, {'text': 'attention,', 'start': 7.679, 'end': 8.659}, {'text': 'and', 'start': 8.699, 'end': 8.86}, {'text': 'three', 'start': 8.88, 'end': 9.06}, {'text': 'out', 'start': 9.079, 'end': 9.18}, {'text': 'of', 'start': 9.199, 'end': 9.34}, {'text': 'four', 'start': 9.38, 'end': 9.799}, {'text': 'said', 'start': 9.84, 'end': 10.0}, {'text': 'you', 'start': 10.019, 'end': 10.159}, {'text': 'know', 'start': 10.179, 'end': 10.36}, {'text': 'the', 'start': 10.38, 'end': 10.42}, {'text': 'look', 'start': 10.519, 'end': 10.699}, {'text': 'you', 'start': 10.739, 'end': 10.859}, {'text': 'want,', 'start': 10.98, 'end': 11.34}, {'text': 'but', 'start': 11.359, 'end': 11.52}, {'text': "don't", 'start': 11.56, 'end': 11.779}, {'text': 'have', 'start': 11.819, 'end': 11.94}, {'text': 'the', 'start': 11.96, 'end': 12.06}, {'text': 'editing', 'start': 12.079, 'end': 12.4}, {'text': 'skills', 'start': 12.52, 'end': 12.859}, {'text': 'to', 'start': 12.88, 'end': 13.0}, {'text': 'get', 'start': 13.019, 'end': 13.18}, {'text': 'there.', 'start': 13.22, 'end': 14.22}, {'text': 'So', 'start': 14.239, 'end': 14.399}, {'text': 'we', 'start': 14.42, 'end': 14.52}, {'text': 'built', 'start': 14.619, 'end': 14.88}, {'text': 'Editor', 'start': 15.079, 'end': 15.42}, {'text': 'Agent.', 'start': 15.619, 'end': 16.02}];
(function () {
const TRANSCRIPT = [
{ text: "We", start: 0.119, end: 0.259 },
{ text: "asked", start: 0.319, end: 0.479 },
{ text: "what", start: 0.519, end: 0.659 },
{ text: "you", start: 0.699, end: 0.819 },
{ text: "needed.", start: 0.859, end: 1.819 },
{ text: "Forty-seven", start: 1.86, end: 2.299 },
{ text: "percent", start: 2.399, end: 2.679 },
{ text: "of", start: 2.7, end: 2.799 },
{ text: "you", start: 2.839, end: 2.939 },
{ text: "said", start: 3.039, end: 3.179 },
{ text: "motion", start: 3.24, end: 3.559 },
{ text: "graphics,", start: 3.579, end: 4.599 },
{ text: "sixty-two", start: 4.679, end: 5.179 },
{ text: "percent", start: 5.299, end: 5.759 },
{ text: "said", start: 5.859, end: 5.98 },
{ text: "static", start: 6.079, end: 6.399 },
{ text: "content", start: 6.46, end: 6.879 },
{ text: "was", start: 6.92, end: 7.079 },
{ text: "costing", start: 7.099, end: 7.48 },
{ text: "you", start: 7.5, end: 7.579 },
{ text: "attention,", start: 7.679, end: 8.659 },
{ text: "and", start: 8.699, end: 8.86 },
{ text: "three", start: 8.88, end: 9.06 },
{ text: "out", start: 9.079, end: 9.18 },
{ text: "of", start: 9.199, end: 9.34 },
{ text: "four", start: 9.38, end: 9.799 },
{ text: "said", start: 9.84, end: 10.0 },
{ text: "you", start: 10.019, end: 10.159 },
{ text: "know", start: 10.179, end: 10.36 },
{ text: "the", start: 10.38, end: 10.42 },
{ text: "look", start: 10.519, end: 10.699 },
{ text: "you", start: 10.739, end: 10.859 },
{ text: "want,", start: 10.98, end: 11.34 },
{ text: "but", start: 11.359, end: 11.52 },
{ text: "don't", start: 11.56, end: 11.779 },
{ text: "have", start: 11.819, end: 11.94 },
{ text: "the", start: 11.96, end: 12.06 },
{ text: "editing", start: 12.079, end: 12.4 },
{ text: "skills", start: 12.52, end: 12.859 },
{ text: "to", start: 12.88, end: 13.0 },
{ text: "get", start: 13.019, end: 13.18 },
{ text: "there.", start: 13.22, end: 14.22 },
{ text: "So", start: 14.239, end: 14.399 },
{ text: "we", start: 14.42, end: 14.52 },
{ text: "built", start: 14.619, end: 14.88 },
{ text: "Editor", start: 15.079, end: 15.42 },
{ text: "Agent.", start: 15.619, end: 16.02 },
];
const tl = gsap.timeline({ paused: true });
// 1. Intro (0-1.8s)
tl.set('.intro-container', { opacity: 1 }, 0);
tl.from('.black-circle', { scale: 0, duration: 0.3, ease: 'power2.out' }, 0);
tl.from('.intro-text', { x: -100, opacity: 0, duration: 0.3, ease: 'power2.out' }, 0.1);
tl.set('.intro-container', { opacity: 0 }, 1.8);
tl.set(".intro-container", { opacity: 1 }, 0);
tl.from(".black-circle", { scale: 0, duration: 0.3, ease: "power2.out" }, 0);
tl.from(".intro-text", { x: -100, opacity: 0, duration: 0.3, ease: "power2.out" }, 0.1);
tl.set(".intro-container", { opacity: 0 }, 1.8);
// 2. Stat 1 (1.86s - 4.6s) - "Forty-seven percent"
const stat1Time = 1.86;
tl.set('.stat-1', { opacity: 1 }, stat1Time);
tl.from('.stat-1 .vermillion-square', { x: -1000, duration: 0.3, ease: 'power2.out' }, stat1Time);
tl.from('.stat-1 .stat-number', { opacity: 0, scale: 0.8, duration: 0.2, ease: 'power2.out' }, stat1Time + 0.1);
tl.from('.stat-1 .stat-subtext', { opacity: 0, y: 20, duration: 0.2, ease: 'power2.out' }, stat1Time + 0.2);
tl.set('.stat-1', { opacity: 0 }, 4.6);
tl.set(".stat-1", { opacity: 1 }, stat1Time);
tl.from(
".stat-1 .vermillion-square",
{ x: -1000, duration: 0.3, ease: "power2.out" },
stat1Time,
);
tl.from(
".stat-1 .stat-number",
{ opacity: 0, scale: 0.8, duration: 0.2, ease: "power2.out" },
stat1Time + 0.1,
);
tl.from(
".stat-1 .stat-subtext",
{ opacity: 0, y: 20, duration: 0.2, ease: "power2.out" },
stat1Time + 0.2,
);
tl.set(".stat-1", { opacity: 0 }, 4.6);
// 3. Stat 2 (4.679s - 8.8s) - "Sixty-two percent"
const stat2Time = 4.679;
tl.set('.stat-2', { opacity: 1 }, stat2Time);
tl.from('.stat-2 .white-circle', { scale: 0, duration: 0.3, ease: 'power2.out' }, stat2Time);
tl.set('.stat-2', { opacity: 0 }, 8.8);
tl.set(".stat-2", { opacity: 1 }, stat2Time);
tl.from(
".stat-2 .white-circle",
{ scale: 0, duration: 0.3, ease: "power2.out" },
stat2Time,
);
tl.set(".stat-2", { opacity: 0 }, 8.8);
// 4. Stat 3 (8.88s - 14.2s) - "Three out of four"
const stat3Time = 8.88;
tl.set('.stat-3', { opacity: 1 }, stat3Time);
tl.from('.stat-3 .black-rectangle', { width: 0, duration: 0.3, ease: 'power2.out' }, stat3Time);
tl.from('.stat-3 .stat-number', { opacity: 0, y: -30, duration: 0.2, ease: 'power2.out' }, stat3Time + 0.1);
tl.from('.stat-3 .stat-subtext', { opacity: 0, y: 20, duration: 0.2, ease: 'power2.out' }, stat3Time + 0.2);
tl.set('.stat-3', { opacity: 0 }, 14.2);
tl.set(".stat-3", { opacity: 1 }, stat3Time);
tl.from(
".stat-3 .black-rectangle",
{ width: 0, duration: 0.3, ease: "power2.out" },
stat3Time,
);
tl.from(
".stat-3 .stat-number",
{ opacity: 0, y: -30, duration: 0.2, ease: "power2.out" },
stat3Time + 0.1,
);
tl.from(
".stat-3 .stat-subtext",
{ opacity: 0, y: 20, duration: 0.2, ease: "power2.out" },
stat3Time + 0.2,
);
tl.set(".stat-3", { opacity: 0 }, 14.2);
// 5. Outro (14.239s - 17s) - "So we built Editor Agent"
tl.set('.outro-container', { opacity: 1 }, 14.239);
tl.from('.outro-circle', { scale: 0, duration: 0.3, ease: 'power2.out' }, 14.239);
tl.from('.outro-text', { scale: 1.5, opacity: 0, duration: 0.3, ease: 'power2.out' }, 14.3);
tl.set(".outro-container", { opacity: 1 }, 14.239);
tl.from(".outro-circle", { scale: 0, duration: 0.3, ease: "power2.out" }, 14.239);
tl.from(".outro-text", { scale: 1.5, opacity: 0, duration: 0.3, ease: "power2.out" }, 14.3);
window.__timelines["graphics-comp"] = tl;
})();
@@ -1,6 +1,7 @@
# HyperFrames Design Review
## First Impression
This looks like a PowerPoint presentation from a 2010 corporate retreat that's trying way too hard to be "modern." Its a chaotic mess of geometric shapes and primary colors that lacks any sense of sophisticated art direction.
---
@@ -10,18 +11,21 @@ This looks like a PowerPoint presentation from a 2010 corporate retreat that's t
Issues that make this look unprofessional or straight-up ugly. These MUST be fixed.
### The "Primary School" Color Palette
**Where:** `compositions/graphics.html`
**What's wrong:** You're using `#D0021B` (a generic, aggressive red), pure black `#000000`, and pure white `#FFFFFF`. Its the most basic, uninspired color combination possible. It lacks depth, vibration, or any sense of modern aesthetic.
**Why it matters:** It looks cheap and amateur. High-end design uses nuanced tones, not the default colors from a 1995 Windows paint bucket.
**Fix it:** Move to a more sophisticated palette. Try a deep crimson or a vibrant coral instead of that "stop sign" red. Use an off-white or a very light gray (`#F5F5F5`) instead of pure white to reduce eye strain and look more "editorial."
### Typography Hierarchy is Non-Existent
**Where:** `compositions/graphics.html` and `compositions/captions.html`
**What's wrong:** Everything is just "BIG AND BOLD." You're using `font-weight: 900` for everything from the 200px stats to the 56px captions. When everything is shouting, nothing is heard.
**Why it matters:** There's no visual path for the eye to follow. The viewer is just bombarded with heavy blocks of text.
**Fix it:** Introduce contrast in weight. Use a lighter weight (300 or 400) for subtext and captions to let the big numbers actually pop. Vary the tracking (letter-spacing) more intentionally.
### The "Floating Box" Caption Aesthetic
**Where:** `compositions/captions.html`
**What's wrong:** A solid black rectangle with white text slapped on the bottom. Its the "default" look of every low-budget social media video.
**Why it matters:** It obscures the composition and looks like an afterthought rather than an integrated design element.
@@ -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 Curves
**Where:** `index.html` and `compositions/graphics.html`
**The problem:** You're using `power2.out` for almost everything. Its the "safe" choice, which makes it the "boring" choice. The transitions feel mechanical and predictable.
**Make it better:** Use more expressive easing. Try `expo.out` for faster, snappier entrances, or `back.out(1.7)` for a slight overshoot that gives the geometric shapes some "weight" and personality.
### Static Background Void
**Where:** `index.html` (`#bg-shapes`)
**The problem:** You have a layer for background shapes that is completely empty. The video just sits on a flat white or black void when it's scaled down.
**Make it better:** Actually use that layer. Add some subtle, slow-moving geometric patterns or a slight grain texture to give the composition some "atmosphere" so the A-roll doesn't look like it's floating in a vacuum.
@@ -1,130 +1,196 @@
<!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>Geometric Bold - Ikko Tanaka Style</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: 1920px;
height: 1080px;
overflow: hidden;
background-color: #FFFFFF;
}
body,
html {
margin: 0;
padding: 0;
width: 1920px;
height: 1080px;
overflow: hidden;
background-color: #ffffff;
}
#main-canvas {
width: 100%;
height: 100%;
position: relative;
}
#main-canvas {
width: 100%;
height: 100%;
position: relative;
}
.aroll-container {
position: absolute;
overflow: hidden;
border-radius: 12px;
background: #000;
}
.aroll-container {
position: absolute;
overflow: hidden;
border-radius: 12px;
background: #000;
}
#aroll-video {
width: 100%;
height: 100%;
object-fit: cover;
}
#aroll-video {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Background Shapes Layer */
#bg-shapes {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
/* Background Shapes Layer */
#bg-shapes {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
</style>
</head>
<body>
<div id="main-canvas" data-composition-id="main-video" data-width="1920" data-height="1080" data-duration="17">
<video id="aroll-video"
data-start="0"
data-track-index="1"
class="aroll-container"
style="width: 1920px; height: 1080px; top: 0; left: 0; position: absolute; overflow: hidden; border-radius: 12px; object-fit: cover; background: #000;"
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/uploaded_assets/743011f1_e3c6afe3b7aa42369ce01e4961c60e22.mp4">
</video>
<!-- Background Shapes Layer -->
<div id="bg-shapes" data-composition-id="bg-layer" data-width="1920" data-height="1080" data-start="0" data-duration="17" data-track-index="0">
<script>
const bgTl = gsap.timeline({ paused: true });
window.__timelines["bg-layer"] = bgTl;
</script>
</div>
<!-- Intro / Graphics Layer -->
<div id="graphics-layer"
data-composition-id="graphics-comp"
data-composition-src="compositions/graphics.html"
data-start="0"
data-duration="17"
data-track-index="2">
</div>
<!-- Captions Layer -->
<div id="captions-layer"
data-composition-id="captions-comp"
data-composition-src="compositions/captions.html"
data-start="0"
data-duration="17"
data-track-index="3">
</div>
<!-- Transition SFX -->
<audio id="click-sfx" data-start="0" data-track-index="4" src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/generated_assets/853dda23_70261e8b676444bfbfe147e34803851e.mp3"></audio>
</head>
<body>
<div
id="main-canvas"
data-composition-id="main-video"
data-width="1920"
data-height="1080"
data-duration="17"
>
<video
id="aroll-video"
data-start="0"
data-track-index="1"
class="aroll-container"
style="
width: 1920px;
height: 1080px;
top: 0;
left: 0;
position: absolute;
overflow: hidden;
border-radius: 12px;
object-fit: cover;
background: #000;
"
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/uploaded_assets/743011f1_e3c6afe3b7aa42369ce01e4961c60e22.mp4"
></video>
<!-- Background Shapes Layer -->
<div
id="bg-shapes"
data-composition-id="bg-layer"
data-width="1920"
data-height="1080"
data-start="0"
data-duration="17"
data-track-index="0"
>
<script>
const tl = gsap.timeline({ paused: true });
const aroll = document.getElementById('aroll-video');
// --- A-ROLL FRAMING LOGIC (LANDSCAPE 1920x1080) ---
// 0-3s: Intro - Slide in from right & Scale. Full screen.
tl.fromTo(aroll,
{ x: 1920, scale: 0.8 },
{ x: 0, scale: 1, duration: 0.3, ease: "power2.out" }, 0);
// Moment 1: 1.86s (Transition to first stat: "Forty-seven percent")
// Scale down to 60%, reposition to right side (next to graphic)
tl.to(aroll, {
width: 1152, height: 648, x: 700, y: 216,
duration: 0.3, ease: "power2.out"
}, 1.86);
// Moment 2: 4.679s (Transition to second stat: "Sixty-two percent")
// Shift to left side (next to graphic)
tl.to(aroll, {
x: 68, y: 216,
duration: 0.3, ease: "power2.out"
}, 4.679);
// Moment 3: 8.88s (Transition to third stat: "Three out of four")
// Center and scale down (graphic will be above/below)
tl.to(aroll, {
width: 960, height: 540, x: 480, y: 450,
duration: 0.3, ease: "power2.out"
}, 8.88);
// Moment 4: 14.239s (Closing/Editor Agent Reveal: "So we built...")
// Full screen zoom center
tl.to(aroll, {
width: 1920, height: 1080, x: 0, y: 0, scale: 1,
duration: 0.3, ease: "power2.out"
}, 14.239);
window.__timelines["main-video"] = tl;
const bgTl = gsap.timeline({ paused: true });
window.__timelines["bg-layer"] = bgTl;
</script>
</div>
<!-- Intro / Graphics Layer -->
<div
id="graphics-layer"
data-composition-id="graphics-comp"
data-composition-src="compositions/graphics.html"
data-start="0"
data-duration="17"
data-track-index="2"
></div>
<!-- Captions Layer -->
<div
id="captions-layer"
data-composition-id="captions-comp"
data-composition-src="compositions/captions.html"
data-start="0"
data-duration="17"
data-track-index="3"
></div>
<!-- Transition SFX -->
<audio
id="click-sfx"
data-start="0"
data-track-index="4"
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/generated_assets/853dda23_70261e8b676444bfbfe147e34803851e.mp3"
></audio>
<script>
const tl = gsap.timeline({ paused: true });
const aroll = document.getElementById("aroll-video");
// --- A-ROLL FRAMING LOGIC (LANDSCAPE 1920x1080) ---
// 0-3s: Intro - Slide in from right & Scale. Full screen.
tl.fromTo(
aroll,
{ x: 1920, scale: 0.8 },
{ x: 0, scale: 1, duration: 0.3, ease: "power2.out" },
0,
);
// Moment 1: 1.86s (Transition to first stat: "Forty-seven percent")
// Scale down to 60%, reposition to right side (next to graphic)
tl.to(
aroll,
{
width: 1152,
height: 648,
x: 700,
y: 216,
duration: 0.3,
ease: "power2.out",
},
1.86,
);
// Moment 2: 4.679s (Transition to second stat: "Sixty-two percent")
// Shift to left side (next to graphic)
tl.to(
aroll,
{
x: 68,
y: 216,
duration: 0.3,
ease: "power2.out",
},
4.679,
);
// Moment 3: 8.88s (Transition to third stat: "Three out of four")
// Center and scale down (graphic will be above/below)
tl.to(
aroll,
{
width: 960,
height: 540,
x: 480,
y: 450,
duration: 0.3,
ease: "power2.out",
},
8.88,
);
// Moment 4: 14.239s (Closing/Editor Agent Reveal: "So we built...")
// Full screen zoom center
tl.to(
aroll,
{
width: 1920,
height: 1080,
x: 0,
y: 0,
scale: 1,
duration: 0.3,
ease: "power2.out",
},
14.239,
);
window.__timelines["main-video"] = tl;
</script>
</div>
</body>
</body>
</html>