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: 4
- Critical issues: 0
- Overall compliance status: PASS
## Critical Issues
None. The compositions follow the HyperFrame schema correctly, including deterministic logic, finite timelines, and proper registration.
## 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,25 +29,33 @@ None. The compositions follow the HyperFrame schema correctly, including determi
- [x] No infinite or zero-duration timelines
### [index.html]
**Status**: COMPLIANT
**Issues Found**:
- None. The root composition correctly orchestrates sub-compositions and the A-roll video.
### [compositions/bg-grid.html]
**Status**: COMPLIANT
**Issues Found**:
- None. The script uses deterministic loops and fixed arrays for cube placement. The timeline is registered correctly.
### [compositions/mg-overlays.html]
**Status**: COMPLIANT
**Issues Found**:
- None. The script uses a finite loop for the background grid pulse instead of an infinite repeat, ensuring a finite timeline.
### [compositions/captions.html]
**Status**: COMPLIANT
**Issues Found**:
- None. Captions are grouped and animated deterministically based on the transcript.
@@ -1,5 +1,10 @@
<template id="bg-grid-template">
<div data-composition-id="bg-grid-comp" data-width="1080" data-height="1920" data-duration="13.88">
<div
data-composition-id="bg-grid-comp"
data-width="1080"
data-height="1920"
data-duration="13.88"
>
<div class="grid-container" id="grid-container"></div>
<div class="wash-container" id="wash-container"></div>
<div class="cubes-container" id="cubes-container"></div>
@@ -10,7 +15,7 @@
height: 1920px;
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.42) 0%, rgba(255, 255, 255, 0) 24%),
linear-gradient(180deg, #F7F2E9 0%, #EFE8DD 100%);
linear-gradient(180deg, #f7f2e9 0%, #efe8dd 100%);
position: relative;
overflow: hidden;
}
@@ -35,7 +40,7 @@
[data-composition-id="bg-grid-comp"] .grid-line {
position: absolute;
background-color: #1E1E1E;
background-color: #1e1e1e;
opacity: 0;
}
@@ -71,7 +76,7 @@
[data-composition-id="bg-grid-comp"] .cube-path {
fill: none;
stroke: #1E1E1E;
stroke: #1e1e1e;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
@@ -83,7 +88,7 @@
</style>
<script>
(function() {
(function () {
const compId = "bg-grid-comp";
const width = 1080;
const height = 1920;
@@ -92,76 +97,88 @@
const cellW = width / cols;
const cellH = height / rows;
const container = document.getElementById('grid-container');
const washContainer = document.getElementById('wash-container');
const cubesContainer = document.getElementById('cubes-container');
const container = document.getElementById("grid-container");
const washContainer = document.getElementById("wash-container");
const cubesContainer = document.getElementById("cubes-container");
const tl = gsap.timeline({ paused: true });
const washBands = [
{ x: 0, y: 213.33, w: 324, h: 320, color: 'rgba(204, 51, 51, 0.08)' },
{ x: 648, y: 0, w: 432, h: 426.67, color: 'rgba(51, 119, 187, 0.08)' },
{ x: 756, y: 1280, w: 324, h: 320, color: 'rgba(51, 119, 187, 0.05)' },
{ x: 0, y: 1493.33, w: 432, h: 426.67, color: 'rgba(30, 30, 30, 0.05)' }
{ x: 0, y: 213.33, w: 324, h: 320, color: "rgba(204, 51, 51, 0.08)" },
{ x: 648, y: 0, w: 432, h: 426.67, color: "rgba(51, 119, 187, 0.08)" },
{ x: 756, y: 1280, w: 324, h: 320, color: "rgba(51, 119, 187, 0.05)" },
{ x: 0, y: 1493.33, w: 432, h: 426.67, color: "rgba(30, 30, 30, 0.05)" },
];
washBands.forEach((band, index) => {
const el = document.createElement('div');
el.className = 'wash-band';
el.style.left = band.x + 'px';
el.style.top = band.y + 'px';
el.style.width = band.w + 'px';
el.style.height = band.h + 'px';
const el = document.createElement("div");
el.className = "wash-band";
el.style.left = band.x + "px";
el.style.top = band.y + "px";
el.style.width = band.w + "px";
el.style.height = band.h + "px";
el.style.background = band.color;
washContainer.appendChild(el);
tl.to(el, {
opacity: 1,
duration: 0.7,
ease: "power2.out"
}, 0.2 + (index * 0.28));
tl.to(
el,
{
opacity: 1,
duration: 0.7,
ease: "power2.out",
},
0.2 + index * 0.28,
);
});
for (let i = 0; i <= rows; i++) {
const line = document.createElement('div');
line.className = 'grid-line horizontal';
line.style.top = (i * cellH) + 'px';
const line = document.createElement("div");
line.className = "grid-line horizontal";
line.style.top = i * cellH + "px";
container.appendChild(line);
tl.to(line, {
opacity: 0.24,
duration: 0.7,
ease: "expo.out"
}, (i / rows) * 0.48);
tl.to(
line,
{
opacity: 0.24,
duration: 0.7,
ease: "expo.out",
},
(i / rows) * 0.48,
);
}
for (let j = 0; j <= cols; j++) {
const line = document.createElement('div');
line.className = 'grid-line vertical';
line.style.left = (j * cellW) + 'px';
const line = document.createElement("div");
line.className = "grid-line vertical";
line.style.left = j * cellW + "px";
container.appendChild(line);
tl.to(line, {
opacity: 0.24,
duration: 0.7,
ease: "expo.out"
}, (j / cols) * 0.48 + 0.18);
tl.to(
line,
{
opacity: 0.24,
duration: 0.7,
ease: "expo.out",
},
(j / cols) * 0.48 + 0.18,
);
}
const cubeCells = [
{ r: 2, c: 2, color: '#3377BB' },
{ r: 4, c: 7, color: '#CC3333' },
{ r: 8, c: 3, color: '#3377BB' },
{ r: 11, c: 6, color: '#CC3333' },
{ r: 15, c: 8, color: '#3377BB' }
{ r: 2, c: 2, color: "#3377BB" },
{ r: 4, c: 7, color: "#CC3333" },
{ r: 8, c: 3, color: "#3377BB" },
{ r: 11, c: 6, color: "#CC3333" },
{ r: 15, c: 8, color: "#3377BB" },
];
cubeCells.forEach((cell, index) => {
const cellDiv = document.createElement('div');
cellDiv.className = 'cube-cell';
cellDiv.style.width = cellW + 'px';
cellDiv.style.height = cellH + 'px';
cellDiv.style.left = (cell.c * cellW) + 'px';
cellDiv.style.top = (cell.r * cellH) + 'px';
const cellDiv = document.createElement("div");
cellDiv.className = "cube-cell";
cellDiv.style.width = cellW + "px";
cellDiv.style.height = cellH + "px";
cellDiv.style.left = cell.c * cellW + "px";
cellDiv.style.top = cell.r * cellH + "px";
const svg = `
<svg viewBox="0 0 100 100" class="cube-svg">
@@ -176,65 +193,93 @@
cellDiv.innerHTML = svg;
cubesContainer.appendChild(cellDiv);
const paths = cellDiv.querySelectorAll('.cube-path');
const faces = cellDiv.querySelectorAll('.cube-face');
const paths = cellDiv.querySelectorAll(".cube-path");
const faces = cellDiv.querySelectorAll(".cube-face");
paths.forEach(path => {
paths.forEach((path) => {
const length = path.getTotalLength();
gsap.set(path, { strokeDasharray: length, strokeDashoffset: length });
});
const startTime = 1.45 + (index * 1.4);
const startTime = 1.45 + index * 1.4;
paths.forEach((path, pIndex) => {
tl.to(path, {
strokeDashoffset: 0,
duration: 0.95,
ease: "power2.inOut"
}, startTime + (pIndex * 0.2));
tl.to(
path,
{
strokeDashoffset: 0,
duration: 0.95,
ease: "power2.inOut",
},
startTime + pIndex * 0.2,
);
});
faces.forEach((face, fIndex) => {
const faceTime = startTime + 0.8 + (fIndex * 0.1);
tl.to(face, {
opacity: 0.24,
duration: 0.45,
ease: "power2.out"
}, faceTime);
const faceTime = startTime + 0.8 + fIndex * 0.1;
tl.to(
face,
{
opacity: 0.24,
duration: 0.45,
ease: "power2.out",
},
faceTime,
);
tl.to(face, {
opacity: 0.06,
duration: 1.2,
ease: "sine.out"
}, faceTime + 0.45);
tl.to(
face,
{
opacity: 0.06,
duration: 1.2,
ease: "sine.out",
},
faceTime + 0.45,
);
});
tl.to(cellDiv, {
y: -12,
duration: 2.6,
ease: "sine.inOut"
}, startTime + 0.35);
tl.to(
cellDiv,
{
y: -12,
duration: 2.6,
ease: "sine.inOut",
},
startTime + 0.35,
);
tl.to(cellDiv, {
y: -4,
duration: 2.8,
ease: "sine.inOut"
}, startTime + 2.95);
tl.to(
cellDiv,
{
y: -4,
duration: 2.8,
ease: "sine.inOut",
},
startTime + 2.95,
);
});
tl.to(container, {
x: 8,
y: 8,
duration: 13.88,
ease: "none"
}, 0);
tl.to(
container,
{
x: 8,
y: 8,
duration: 13.88,
ease: "none",
},
0,
);
tl.to(cubesContainer, {
x: -6,
y: 4,
duration: 13.88,
ease: "none"
}, 0);
tl.to(
cubesContainer,
{
x: -6,
y: 4,
duration: 13.88,
ease: "none",
},
0,
);
window.__timelines[compId] = tl;
})();
@@ -1,12 +1,17 @@
<template id="captions-template">
<div data-composition-id="captions-comp" data-width="1080" data-height="1920" data-duration="13.88">
<div
data-composition-id="captions-comp"
data-width="1080"
data-height="1920"
data-duration="13.88"
>
<div id="captions-rail">
<div id="captions-kicker">Narration</div>
<div id="captions-container"></div>
</div>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@700;900&display=swap');
@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@700;900&display=swap");
[data-composition-id="captions-comp"] {
width: 1080px;
@@ -21,13 +26,18 @@
bottom: 118px;
width: 864px;
min-height: 258px;
border-top: 2px solid #1E1E1E;
border-top: 2px solid #1e1e1e;
padding-top: 18px;
background: linear-gradient(180deg, rgba(245, 241, 234, 0) 0%, rgba(245, 241, 234, 0.88) 18%, rgba(245, 241, 234, 0.97) 100%);
background: linear-gradient(
180deg,
rgba(245, 241, 234, 0) 0%,
rgba(245, 241, 234, 0.88) 18%,
rgba(245, 241, 234, 0.97) 100%
);
}
[data-composition-id="captions-comp"] #captions-kicker {
font-family: 'IBM Plex Mono', monospace;
font-family: "IBM Plex Mono", monospace;
font-size: 18px;
font-weight: 700;
letter-spacing: 0.24em;
@@ -43,10 +53,10 @@
}
[data-composition-id="captions-comp"] .caption-line {
font-family: 'IBM Plex Mono', monospace;
font-family: "IBM Plex Mono", monospace;
font-size: 56px;
font-weight: 900;
color: #1E1E1E;
color: #1e1e1e;
opacity: 0;
position: absolute;
left: 0;
@@ -62,8 +72,8 @@
</style>
<script>
(function() {
const container = document.getElementById('captions-container');
(function () {
const container = document.getElementById("captions-container");
const tl = gsap.timeline({ paused: true });
const groups = [
@@ -74,31 +84,43 @@
{ text: "and three out of four said you know", start: 7.319, end: 8.739 },
{ text: "the look you want but don't have", start: 8.8, end: 10.3 },
{ text: "the editing skills to get there.", start: 10.5, 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 },
];
groups.forEach(group => {
const el = document.createElement('div');
el.className = 'caption-line';
el.innerHTML = group.text.split(' ').map(word => `<span class="word">${word}</span>`).join(' ');
groups.forEach((group) => {
const el = document.createElement("div");
el.className = "caption-line";
el.innerHTML = group.text
.split(" ")
.map((word) => `<span class="word">${word}</span>`)
.join(" ");
container.appendChild(el);
tl.fromTo(el, {
opacity: 0,
y: 26
}, {
opacity: 1,
y: 0,
duration: 0.18,
ease: "power2.out"
}, group.start);
tl.fromTo(
el,
{
opacity: 0,
y: 26,
},
{
opacity: 1,
y: 0,
duration: 0.18,
ease: "power2.out",
},
group.start,
);
tl.to(el, {
opacity: 0,
y: -12,
duration: 0.12,
ease: "power2.in"
}, group.end);
tl.to(
el,
{
opacity: 0,
y: -12,
duration: 0.12,
ease: "power2.in",
},
group.end,
);
});
window.__timelines["captions-comp"] = tl;
@@ -1,64 +1,137 @@
<template id="mg-overlays-template">
<div data-composition-id="mg-overlays-comp" data-width="1080" data-height="1920" data-duration="13.88">
<div
data-composition-id="mg-overlays-comp"
data-width="1080"
data-height="1920"
data-duration="13.88"
>
<div class="overlay-container">
<div id="system-kicker">Editor Agent / Survey System</div>
<svg id="drawing-canvas" viewBox="0 0 1080 1920" preserveAspectRatio="xMidYMid slice">
<defs>
<pattern id="gridPattern" width="108" height="106.66666666666667" patternUnits="userSpaceOnUse">
<path d="M 108 0 L 0 0 0 106.66666666666667" fill="none" stroke="#1E1E1E" stroke-width="1" opacity="0.12"/>
<pattern
id="gridPattern"
width="108"
height="106.66666666666667"
patternUnits="userSpaceOnUse"
>
<path
d="M 108 0 L 0 0 0 106.66666666666667"
fill="none"
stroke="#1E1E1E"
stroke-width="1"
opacity="0.12"
/>
</pattern>
</defs>
<rect class="ambient-grid" width="100%" height="100%" fill="url(#gridPattern)" />
<g id="structure-1" class="structure" transform="translate(108, 1108)">
<rect class="draw-line" x="0" y="0" width="324" height="245.33" fill="none" stroke="#CC3333" stroke-width="2" />
<rect class="fill-box red" x="0" y="0" width="324" height="245.33" fill="#CC3333" opacity="0" />
<rect
class="draw-line"
x="0"
y="0"
width="324"
height="245.33"
fill="none"
stroke="#CC3333"
stroke-width="2"
/>
<rect
class="fill-box red"
x="0"
y="0"
width="324"
height="245.33"
fill="#CC3333"
opacity="0"
/>
</g>
<g id="structure-2" class="structure" transform="translate(864, 214)">
<rect class="draw-line" x="-270" y="0" width="270" height="224" fill="none" stroke="#3377BB" stroke-width="2" />
<rect class="fill-box blue" x="-270" y="0" width="270" height="224" fill="#3377BB" opacity="0" />
<rect
class="draw-line"
x="-270"
y="0"
width="270"
height="224"
fill="none"
stroke="#3377BB"
stroke-width="2"
/>
<rect
class="fill-box blue"
x="-270"
y="0"
width="270"
height="224"
fill="#3377BB"
opacity="0"
/>
</g>
<g id="structure-3" class="structure" transform="translate(540, 1328)">
<rect class="draw-line" x="0" y="0" width="432" height="245.33" fill="none" stroke="#1E1E1E" stroke-width="2" />
<rect class="fill-box gray" x="0" y="0" width="432" height="245.33" fill="#1E1E1E" opacity="0" />
<rect
class="draw-line"
x="0"
y="0"
width="432"
height="245.33"
fill="none"
stroke="#1E1E1E"
stroke-width="2"
/>
<rect
class="fill-box gray"
x="0"
y="0"
width="432"
height="245.33"
fill="#1E1E1E"
opacity="0"
/>
</g>
</svg>
<div id="content-1" class="content-block" style="top: 1128px; left: 108px; width: 352px;">
<div id="content-1" class="content-block" style="top: 1128px; left: 108px; width: 352px">
<div class="eyebrow">Need motion</div>
<div class="stat-number">47%</div>
<div class="stat-label">Asked for motion graphics</div>
<div class="stat-note">Sharper pacing, clearer transitions, more visual energy.</div>
</div>
<div id="content-2" class="content-block align-right" style="top: 238px; left: 864px; width: 270px; transform: translateX(-100%);">
<div
id="content-2"
class="content-block align-right"
style="top: 238px; left: 864px; width: 270px; transform: translateX(-100%)"
>
<div class="eyebrow">Attention drop</div>
<div class="stat-number">62%</div>
<div class="stat-label">Were stuck with static content</div>
<div class="stat-note">The message was right. The cut was not landing.</div>
</div>
<div id="content-3" class="content-block" style="top: 1348px; left: 540px; width: 432px;">
<div id="content-3" class="content-block" style="top: 1348px; left: 540px; width: 432px">
<div class="eyebrow">Execution gap</div>
<div class="stat-number">75%</div>
<div class="stat-label">Knew the look, needed the edit</div>
<div class="stat-note">The direction was clear. The hands-on workflow was the bottleneck.</div>
<div class="stat-note">
The direction was clear. The hands-on workflow was the bottleneck.
</div>
</div>
</div>
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;700&display=swap');
@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;700&display=swap");
[data-composition-id="mg-overlays-comp"] .overlay-container {
width: 1080px;
height: 1920px;
position: relative;
color: #1E1E1E;
font-family: 'IBM Plex Mono', monospace;
color: #1e1e1e;
font-family: "IBM Plex Mono", monospace;
pointer-events: none;
}
@@ -85,7 +158,7 @@
opacity: 0;
z-index: 100;
padding-top: 18px;
border-top: 2px solid #1E1E1E;
border-top: 2px solid #1e1e1e;
}
[data-composition-id="mg-overlays-comp"] .content-block.align-right {
@@ -93,7 +166,7 @@
}
[data-composition-id="mg-overlays-comp"] #content-2 {
border-top-color: #3377BB;
border-top-color: #3377bb;
}
[data-composition-id="mg-overlays-comp"] .eyebrow {
@@ -108,7 +181,7 @@
font-size: 132px;
font-weight: 700;
line-height: 0.92;
color: #1E1E1E;
color: #1e1e1e;
}
[data-composition-id="mg-overlays-comp"] .stat-label {
@@ -132,11 +205,11 @@
}
[data-composition-id="mg-overlays-comp"] #content-1 .stat-number {
color: #CC3333;
color: #cc3333;
}
[data-composition-id="mg-overlays-comp"] #content-2 .stat-number {
color: #3377BB;
color: #3377bb;
}
[data-composition-id="mg-overlays-comp"] #content-2 .stat-label {
@@ -150,59 +223,73 @@
</style>
<script>
(function() {
(function () {
const tl = gsap.timeline({ paused: true });
const revealStat = ({
start,
end,
structure,
fill,
content,
fromX = 0,
fromY = 0,
}) => {
tl.to(`${structure} .draw-line`, {
strokeDashoffset: 0,
duration: 0.75,
ease: "power2.out"
}, start);
const revealStat = ({ start, end, structure, fill, content, fromX = 0, fromY = 0 }) => {
tl.to(
`${structure} .draw-line`,
{
strokeDashoffset: 0,
duration: 0.75,
ease: "power2.out",
},
start,
);
tl.to(fill, {
opacity: 0.1,
duration: 0.32,
ease: "power2.out"
}, start + 0.26);
tl.to(
fill,
{
opacity: 0.1,
duration: 0.32,
ease: "power2.out",
},
start + 0.26,
);
tl.fromTo(content, {
opacity: 0,
x: fromX,
y: fromY
}, {
opacity: 1,
x: 0,
y: 0,
duration: 0.55,
ease: "power3.out"
}, start + 0.18);
tl.fromTo(
content,
{
opacity: 0,
x: fromX,
y: fromY,
},
{
opacity: 1,
x: 0,
y: 0,
duration: 0.55,
ease: "power3.out",
},
start + 0.18,
);
tl.to([content, structure], {
opacity: 0,
y: -10,
duration: 0.28,
ease: "power2.in"
}, end - 0.28);
tl.to(
[content, structure],
{
opacity: 0,
y: -10,
duration: 0.28,
ease: "power2.in",
},
end - 0.28,
);
};
tl.fromTo("#system-kicker", {
opacity: 0,
y: -18
}, {
opacity: 1,
y: 0,
duration: 0.5,
ease: "power2.out"
}, 0.35);
tl.fromTo(
"#system-kicker",
{
opacity: 0,
y: -18,
},
{
opacity: 1,
y: 0,
duration: 0.5,
ease: "power2.out",
},
0.35,
);
revealStat({
start: 1.199,
@@ -210,7 +297,7 @@
structure: "#structure-1",
fill: "#structure-1 .fill-box.red",
content: "#content-1",
fromY: 22
fromY: 22,
});
revealStat({
@@ -219,7 +306,7 @@
structure: "#structure-2",
fill: "#structure-2 .fill-box.blue",
content: "#content-2",
fromX: 26
fromX: 26,
});
revealStat({
@@ -228,26 +315,38 @@
structure: "#structure-3",
fill: "#structure-3 .fill-box.gray",
content: "#content-3",
fromY: -22
fromY: -22,
});
tl.to(".ambient-grid", {
opacity: 0.22,
duration: 4.6,
ease: "sine.inOut"
}, 0);
tl.to(
".ambient-grid",
{
opacity: 0.22,
duration: 4.6,
ease: "sine.inOut",
},
0,
);
tl.to(".ambient-grid", {
opacity: 0.1,
duration: 4.64,
ease: "sine.inOut"
}, 4.6);
tl.to(
".ambient-grid",
{
opacity: 0.1,
duration: 4.64,
ease: "sine.inOut",
},
4.6,
);
tl.to(".ambient-grid", {
opacity: 0.2,
duration: 4.64,
ease: "sine.inOut"
}, 9.24);
tl.to(
".ambient-grid",
{
opacity: 0.2,
duration: 4.64,
ease: "sine.inOut",
},
9.24,
);
window.__timelines["mg-overlays-comp"] = tl;
})();
@@ -1,6 +1,7 @@
# HyperFrames Design Review
## First Impression
This looks like a "Sol LeWitt" tribute act performed by someone who only saw a thumbnail of his work on a broken phone. Its a sterile, confused mess that tries to be "minimalist" but ends up just being "unfinished."
---
@@ -8,18 +9,21 @@ This looks like a "Sol LeWitt" tribute act performed by someone who only saw a t
## CRITICAL Design Failures
### Typographic Identity Crisis
**Where:** `compositions/mg-overlays.html` and `compositions/captions.html`
**What's wrong:** You're mixing **IBM Plex Mono** (a technical, rigid font) for your "data" with **Inter** (the most overused, generic UI font in existence) for your captions. Its a jarring clash of "I'm a coder" and "I'm a SaaS landing page from 2019."
**Why it matters:** It destroys any sense of a cohesive visual brand. The viewer doesn't know if they're watching a technical documentary or a generic corporate explainer.
**Fix it:** Commit to the bit. Use IBM Plex Mono for *everything* to lean into the Sol LeWitt / Blueprint aesthetic, or find a high-contrast serif to actually provide some visual interest.
**Fix it:** Commit to the bit. Use IBM Plex Mono for _everything_ to lean into the Sol LeWitt / Blueprint aesthetic, or find a high-contrast serif to actually provide some visual interest.
### The "Floating in a Void" Problem
**Where:** `compositions/mg-overlays.html`
**What's wrong:** Your stats (`47%`, `62%`, `75%`) are just... there. They have no relationship to the grid or the isometric cubes. They're just floating at arbitrary coordinates like `top: 1200px; left: 100px;`.
**Why it matters:** It looks like a mistake. In a grid-based design, *everything* must respect the grid. If it doesn't, the grid is just useless wallpaper.
**Why it matters:** It looks like a mistake. In a grid-based design, _everything_ must respect the grid. If it doesn't, the grid is just useless wallpaper.
**Fix it:** Align your text blocks strictly to the grid lines defined in `bg-grid.html`. Use the `cellW` and `cellH` logic to position your content so it feels structurally sound.
### Caption Background Cowardice
**Where:** `compositions/captions.html`
**What's wrong:** `background-color: rgba(0, 0, 0, 0.4);` with a `backdrop-filter: blur(4px);`. This is the "I don't know how to handle contrast" starter pack. Its ugly, its muddy, and it obscures your "beautiful" background grid.
**Why it matters:** It creates a heavy, dark blob at the bottom of an otherwise light and airy composition. Its visually exhausting.
@@ -30,11 +34,13 @@ This looks like a "Sol LeWitt" tribute act performed by someone who only saw a t
## Design Improvements
### Robotic Animation Pacing
**Where:** `compositions/bg-grid.html` and `compositions/mg-overlays.html`
**The problem:** Your animations are all using `power2.inOut` or `expo.out`. Its predictable and lacks "soul." The cubes draw themselves, then they pulse, then they float. It feels like a loading screen, not a dynamic video.
**Make it better:** Vary the easing. Use `back.out` for the stats (which you did, barely) but make it more aggressive. Give the grid lines a staggered "wipe" effect rather than just fading in. Make the motion feel like it has momentum.
### Color Palette Anemia
**Where:** `compositions/bg-grid.html`
**The problem:** `#3377BB` and `#CC3333`. These are the default "Blue" and "Red" from a 1990s Excel chart. They are boring, primary, and have zero personality.
**Make it better:** Use more sophisticated tones. Try a deeper Cobalt or a muted Terracotta. Or, go full LeWitt and use high-saturation CMYK-style colors, but give them some breathing room.
@@ -1,167 +1,184 @@
<!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>Editor Agent - Sol LeWitt 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: 1080px;
height: 1920px;
background-color: #F5F1EA;
overflow: hidden;
font-family: 'IBM Plex Mono', 'Courier New', Courier, monospace;
}
body,
html {
margin: 0;
padding: 0;
width: 1080px;
height: 1920px;
background-color: #f5f1ea;
overflow: hidden;
font-family: "IBM Plex Mono", "Courier New", Courier, monospace;
}
#main-canvas {
width: 1080px;
height: 1920px;
position: relative;
overflow: hidden;
background: linear-gradient(180deg, #F6F1E8 0%, #EFE8DE 100%);
}
#main-canvas {
width: 1080px;
height: 1920px;
position: relative;
overflow: hidden;
background: linear-gradient(180deg, #f6f1e8 0%, #efe8de 100%);
}
#bg-grid-comp,
#mg-overlays-comp,
#captions-comp,
#aroll-frame {
position: absolute;
top: 0;
left: 0;
width: 1080px;
height: 1920px;
}
#bg-grid-comp,
#mg-overlays-comp,
#captions-comp,
#aroll-frame {
position: absolute;
top: 0;
left: 0;
width: 1080px;
height: 1920px;
}
#bg-grid-comp {
z-index: 0;
}
#bg-grid-comp {
z-index: 0;
}
#aroll-frame {
top: 188px;
left: 108px;
width: 756px;
height: 1180px;
background: #111111;
overflow: hidden;
border: 2px solid #1D1D1D;
box-shadow: 0 22px 48px rgba(17, 17, 17, 0.16);
z-index: 10;
}
#aroll-frame {
top: 188px;
left: 108px;
width: 756px;
height: 1180px;
background: #111111;
overflow: hidden;
border: 2px solid #1d1d1d;
box-shadow: 0 22px 48px rgba(17, 17, 17, 0.16);
z-index: 10;
}
#aroll-frame::before {
content: "";
position: absolute;
inset: 14px;
border: 1px solid rgba(255, 255, 255, 0.28);
pointer-events: none;
z-index: 3;
}
#aroll-frame::before {
content: "";
position: absolute;
inset: 14px;
border: 1px solid rgba(255, 255, 255, 0.28);
pointer-events: none;
z-index: 3;
}
#aroll-video,
#aroll-frame img.__render_frame__,
#aroll-frame img.__preview_render_frame__ {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
filter: saturate(0.88) contrast(1.06) brightness(0.97);
}
#aroll-video,
#aroll-frame img.__render_frame__,
#aroll-frame img.__preview_render_frame__ {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
filter: saturate(0.88) contrast(1.06) brightness(0.97);
}
.frame-meta {
position: absolute;
left: 18px;
right: 18px;
display: flex;
justify-content: space-between;
align-items: center;
color: rgba(255, 255, 255, 0.9);
font-size: 18px;
letter-spacing: 0.18em;
text-transform: uppercase;
z-index: 4;
pointer-events: none;
}
.frame-meta {
position: absolute;
left: 18px;
right: 18px;
display: flex;
justify-content: space-between;
align-items: center;
color: rgba(255, 255, 255, 0.9);
font-size: 18px;
letter-spacing: 0.18em;
text-transform: uppercase;
z-index: 4;
pointer-events: none;
}
.frame-meta.top {
top: 18px;
}
.frame-meta.top {
top: 18px;
}
.frame-meta.bottom {
bottom: 18px;
}
.frame-meta.bottom {
bottom: 18px;
}
#mg-overlays-comp {
z-index: 20;
}
#mg-overlays-comp {
z-index: 20;
}
#captions-comp {
z-index: 30;
pointer-events: none;
}
#captions-comp {
z-index: 30;
pointer-events: none;
}
</style>
</head>
<body>
<div id="main-canvas" data-composition-id="main-comp" data-width="1080" data-height="1920" data-start="0" data-duration="13.88">
<div id="bg-grid-comp"
data-composition-id="bg-grid-comp"
data-composition-src="compositions/bg-grid.html"
data-start="0"
data-duration="13.88"
data-track-index="1">
</head>
<body>
<div
id="main-canvas"
data-composition-id="main-comp"
data-width="1080"
data-height="1920"
data-start="0"
data-duration="13.88"
>
<div
id="bg-grid-comp"
data-composition-id="bg-grid-comp"
data-composition-src="compositions/bg-grid.html"
data-start="0"
data-duration="13.88"
data-track-index="1"
></div>
<div id="aroll-frame">
<div class="frame-meta top">
<span>Editor Agent</span>
<span>Portrait System</span>
</div>
<div id="aroll-frame">
<div class="frame-meta top">
<span>Editor Agent</span>
<span>Portrait System</span>
</div>
<video id="aroll-video"
data-start="0"
data-duration="13.88"
data-track-index="2"
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/uploaded_assets/a8bed725_8ae955c61e3141e09d9eadb97e0eef93.mp4">
</video>
<div class="frame-meta bottom">
<span>Survey Cut</span>
<span>13.88s</span>
</div>
<video
id="aroll-video"
data-start="0"
data-duration="13.88"
data-track-index="2"
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/uploaded_assets/a8bed725_8ae955c61e3141e09d9eadb97e0eef93.mp4"
></video>
<div class="frame-meta bottom">
<span>Survey Cut</span>
<span>13.88s</span>
</div>
</div>
<div id="mg-overlays-comp"
data-composition-id="mg-overlays-comp"
data-composition-src="compositions/mg-overlays.html"
data-start="0"
data-duration="13.88"
data-track-index="3">
</div>
<div
id="mg-overlays-comp"
data-composition-id="mg-overlays-comp"
data-composition-src="compositions/mg-overlays.html"
data-start="0"
data-duration="13.88"
data-track-index="3"
></div>
<div id="captions-comp"
data-composition-id="captions-comp"
data-composition-src="compositions/captions.html"
data-start="0"
data-duration="13.88"
data-track-index="4">
</div>
<div
id="captions-comp"
data-composition-id="captions-comp"
data-composition-src="compositions/captions.html"
data-start="0"
data-duration="13.88"
data-track-index="4"
></div>
<script>
const tl = gsap.timeline({ paused: true });
<script>
const tl = gsap.timeline({ paused: true });
tl.fromTo('#aroll-frame', {
y: 18,
scale: 1.02
}, {
y: 0,
scale: 1,
duration: 0.9,
ease: "power2.out"
}, 0);
tl.fromTo(
"#aroll-frame",
{
y: 18,
scale: 1.02,
},
{
y: 0,
scale: 1,
duration: 0.9,
ease: "power2.out",
},
0,
);
window.__timelines["main-comp"] = tl;
</script>
window.__timelines["main-comp"] = tl;
</script>
</div>
</body>
</body>
</html>