mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-14 00:00:17 +00:00
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:
@@ -1,12 +1,7 @@
|
||||
{
|
||||
"name": "style-4-prod",
|
||||
"description": "Regression fixture imported from normalized style pack style-4-prod",
|
||||
"tags": [
|
||||
"style-regression",
|
||||
"prod-style",
|
||||
"slow",
|
||||
"landscape"
|
||||
],
|
||||
"tags": ["style-regression", "prod-style", "slow", "landscape"],
|
||||
"minPsnr": 30,
|
||||
"maxFrameFailures": 0,
|
||||
"minAudioCorrelation": 0.9,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,14 +1,17 @@
|
||||
# HyperFrame Schema Compliance Review
|
||||
|
||||
## Executive Summary
|
||||
|
||||
- Total files reviewed: 4
|
||||
- Critical issues: 0
|
||||
- Overall compliance status: PASS
|
||||
|
||||
## Critical Issues
|
||||
|
||||
None found. The compositions follow the deterministic requirements and structural rules of the HyperFrame schema.
|
||||
|
||||
## 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 found. The compositions follow the deterministic requirements and structura
|
||||
## File Analysis
|
||||
|
||||
### index.html
|
||||
|
||||
**Status**: COMPLIANT
|
||||
|
||||
**Observations**:
|
||||
|
||||
- Correctly defines the root composition `main-video`.
|
||||
- Uses `data-composition-src` to load sub-compositions.
|
||||
- Properly registers the master timeline in `window.__timelines`.
|
||||
@@ -38,27 +43,33 @@ None found. The compositions follow the deterministic requirements and structura
|
||||
- Note: The `grain-overlay` is defined as an inline composition, which is acceptable for simple effects.
|
||||
|
||||
### compositions/intro.html
|
||||
|
||||
**Status**: COMPLIANT
|
||||
|
||||
**Observations**:
|
||||
|
||||
- Uses `<template>` tag as required.
|
||||
- Root element has `data-composition-id`, `data-width`, `data-height`, and `data-duration`.
|
||||
- Timeline is correctly registered and scoped within an IIFE.
|
||||
- Animation is deterministic.
|
||||
|
||||
### compositions/captions.html
|
||||
|
||||
**Status**: COMPLIANT
|
||||
|
||||
**Observations**:
|
||||
|
||||
- Uses `<template>` tag.
|
||||
- Correctly handles dynamic caption generation within a composition.
|
||||
- Timeline registration is correct.
|
||||
- Deterministic timing based on a static script array.
|
||||
|
||||
### compositions/graphics.html
|
||||
|
||||
**Status**: COMPLIANT
|
||||
|
||||
**Observations**:
|
||||
|
||||
- Uses `<template>` tag.
|
||||
- Root element has all required data attributes.
|
||||
- GSAP animations are deterministic and use explicit durations.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
|
||||
[data-composition-id="captions"] .caption-box {
|
||||
background-color: #7A6248;
|
||||
background-color: #7a6248;
|
||||
padding: 12px 32px;
|
||||
border-radius: 24px;
|
||||
display: flex;
|
||||
@@ -31,8 +31,8 @@
|
||||
}
|
||||
|
||||
[data-composition-id="captions"] .caption-text {
|
||||
color: #F5F0E0;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
color: #f5f0e0;
|
||||
font-family: "Outfit", sans-serif;
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
@@ -42,55 +42,55 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
(function () {
|
||||
const script = [
|
||||
{"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.86},
|
||||
{"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}
|
||||
{ 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.86 },
|
||||
{ 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 },
|
||||
];
|
||||
|
||||
// Group words into lines (max 5 words per line)
|
||||
@@ -98,9 +98,9 @@
|
||||
for (let i = 0; i < script.length; i += 5) {
|
||||
const lineWords = script.slice(i, i + 5);
|
||||
lines.push({
|
||||
text: lineWords.map(w => w.text).join(' '),
|
||||
text: lineWords.map((w) => w.text).join(" "),
|
||||
start: lineWords[0].start,
|
||||
end: lineWords[lineWords.length - 1].end
|
||||
end: lineWords[lineWords.length - 1].end,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -110,21 +110,29 @@
|
||||
|
||||
lines.forEach((line, index) => {
|
||||
// Fade in and set text
|
||||
tl.to(box, {
|
||||
opacity: 1,
|
||||
duration: 0.1,
|
||||
ease: "power2.out",
|
||||
onStart: () => {
|
||||
textEl.textContent = line.text;
|
||||
}
|
||||
}, line.start);
|
||||
tl.to(
|
||||
box,
|
||||
{
|
||||
opacity: 1,
|
||||
duration: 0.1,
|
||||
ease: "power2.out",
|
||||
onStart: () => {
|
||||
textEl.textContent = line.text;
|
||||
},
|
||||
},
|
||||
line.start,
|
||||
);
|
||||
|
||||
// Fade out at the end of the line
|
||||
tl.to(box, {
|
||||
opacity: 0,
|
||||
duration: 0.1,
|
||||
ease: "power2.in"
|
||||
}, line.end);
|
||||
tl.to(
|
||||
box,
|
||||
{
|
||||
opacity: 0,
|
||||
duration: 0.1,
|
||||
ease: "power2.in",
|
||||
},
|
||||
line.end,
|
||||
);
|
||||
});
|
||||
|
||||
window.__timelines["captions"] = tl;
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
<div id="moment-3" class="moment rect-stat">
|
||||
<div class="icon-shape">
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20,20 Q50,0 80,20 Q100,50 80,80 Q50,100 20,80 Q0,50 20,20" fill="currentColor" />
|
||||
<path
|
||||
d="M20,20 Q50,0 80,20 Q100,50 80,80 Q50,100 20,80 Q0,50 20,20"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-text">Editing Skills</div>
|
||||
@@ -28,7 +31,7 @@
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-family: "Outfit", sans-serif;
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -46,7 +49,7 @@
|
||||
[data-composition-id="graphics"] #moment-1 {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
background-color: #3B5E3A;
|
||||
background-color: #3b5e3a;
|
||||
border-radius: 50%;
|
||||
left: 1400px;
|
||||
top: 540px;
|
||||
@@ -72,7 +75,7 @@
|
||||
[data-composition-id="graphics"] #moment-2 {
|
||||
width: 500px;
|
||||
height: 220px;
|
||||
background-color: #CC8832;
|
||||
background-color: #cc8832;
|
||||
border-radius: 110px;
|
||||
left: 960px;
|
||||
top: 200px;
|
||||
@@ -83,7 +86,7 @@
|
||||
[data-composition-id="graphics"] #moment-3 {
|
||||
width: 550px;
|
||||
height: 180px;
|
||||
background-color: #C45D3E;
|
||||
background-color: #c45d3e;
|
||||
border-radius: 40px;
|
||||
left: 400px;
|
||||
top: 540px;
|
||||
@@ -117,41 +120,44 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
(function () {
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
|
||||
// Moment 1: 1.8s - 4.5s
|
||||
// Gentle drift into place and settle
|
||||
tl.fromTo('#moment-1',
|
||||
{ opacity: 0, x: '+=40', y: '+=15', scale: 0.8 },
|
||||
{ opacity: 1, x: 0, y: 0, scale: 1, duration: 1.2, ease: 'back.out(1.7)' },
|
||||
1.8
|
||||
tl.fromTo(
|
||||
"#moment-1",
|
||||
{ opacity: 0, x: "+=40", y: "+=15", scale: 0.8 },
|
||||
{ opacity: 1, x: 0, y: 0, scale: 1, duration: 1.2, ease: "back.out(1.7)" },
|
||||
1.8,
|
||||
);
|
||||
// Hold until 4.5s, then fade out
|
||||
tl.to('#moment-1', { opacity: 0, scale: 0.8, duration: 0.3, ease: 'power2.in' }, 4.2);
|
||||
tl.to("#moment-1", { opacity: 0, scale: 0.8, duration: 0.3, ease: "power2.in" }, 4.2);
|
||||
|
||||
// Moment 2: 4.6s - 8.6s
|
||||
// Gentle drift into place and settle
|
||||
tl.fromTo('#moment-2',
|
||||
{ opacity: 0, y: '-=40', x: '+=10', scale: 0.8 },
|
||||
{ opacity: 1, y: 0, x: 0, scale: 1, duration: 1.2, ease: 'back.out(1.7)' },
|
||||
4.6
|
||||
tl.fromTo(
|
||||
"#moment-2",
|
||||
{ opacity: 0, y: "-=40", x: "+=10", scale: 0.8 },
|
||||
{ opacity: 1, y: 0, x: 0, scale: 1, duration: 1.2, ease: "back.out(1.7)" },
|
||||
4.6,
|
||||
);
|
||||
// Hold until 8.6s, then fade out
|
||||
tl.to('#moment-2', { opacity: 0, scale: 0.8, duration: 0.3, ease: 'power2.in' }, 8.3);
|
||||
tl.to("#moment-2", { opacity: 0, scale: 0.8, duration: 0.3, ease: "power2.in" }, 8.3);
|
||||
|
||||
// Moment 3: 8.8s - 14s
|
||||
// Gentle drift into place and settle
|
||||
tl.fromTo('#moment-3',
|
||||
{ opacity: 0, x: '-=40', y: '-=10', scale: 0.8 },
|
||||
{ opacity: 1, x: 0, y: 0, scale: 1, duration: 1.2, ease: 'back.out(1.7)' },
|
||||
8.8
|
||||
tl.fromTo(
|
||||
"#moment-3",
|
||||
{ opacity: 0, x: "-=40", y: "-=10", scale: 0.8 },
|
||||
{ opacity: 1, x: 0, y: 0, scale: 1, duration: 1.2, ease: "back.out(1.7)" },
|
||||
8.8,
|
||||
);
|
||||
// Hold until end (14s)
|
||||
tl.to('#moment-3', { opacity: 0, duration: 0.5, ease: 'power2.in' }, 13.5);
|
||||
tl.to("#moment-3", { opacity: 0, duration: 0.5, ease: "power2.in" }, 13.5);
|
||||
|
||||
window.__timelines["graphics"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<style>
|
||||
/* Import a rounded humanist sans-serif font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@400;600&display=swap');
|
||||
@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@400;600&display=swap");
|
||||
|
||||
[data-composition-id="intro"] .container {
|
||||
width: 100%;
|
||||
@@ -18,15 +18,15 @@
|
||||
justify-content: flex-start; /* Align to left for speaker card */
|
||||
align-items: center;
|
||||
padding-left: 5%;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-family: "Outfit", sans-serif;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
[data-composition-id="intro"] .title-card {
|
||||
background-color: #3B5E3A; /* Forest Green for contrast */
|
||||
background-color: #3b5e3a; /* Forest Green for contrast */
|
||||
padding: 40px 60px;
|
||||
border-radius: 30px;
|
||||
box-shadow: 0 15px 40px rgba(0,0,0,0.2);
|
||||
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
|
||||
text-align: left;
|
||||
opacity: 0;
|
||||
transform: translateX(-100%); /* Start off-screen left */
|
||||
@@ -35,7 +35,7 @@
|
||||
[data-composition-id="intro"] .title {
|
||||
font-size: 100px;
|
||||
font-weight: 600;
|
||||
color: #F5F0E0; /* Cream text on green card */
|
||||
color: #f5f0e0; /* Cream text on green card */
|
||||
margin: 0;
|
||||
line-height: 1.1;
|
||||
letter-spacing: -2px;
|
||||
@@ -44,31 +44,39 @@
|
||||
[data-composition-id="intro"] .subtitle {
|
||||
font-size: 50px;
|
||||
font-weight: 400;
|
||||
color: #CC8832; /* Ochre accent */
|
||||
color: #cc8832; /* Ochre accent */
|
||||
margin: 10px 0 0 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
(function () {
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
|
||||
|
||||
// Animation: Speaker card slides in from the left
|
||||
tl.to('[data-composition-id="intro"] .title-card', {
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
duration: 0.8,
|
||||
ease: 'power2.out'
|
||||
}, 0.2);
|
||||
tl.to(
|
||||
'[data-composition-id="intro"] .title-card',
|
||||
{
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
duration: 0.8,
|
||||
ease: "power2.out",
|
||||
},
|
||||
0.2,
|
||||
);
|
||||
|
||||
// Exit: Slide off left at 1.8s (synced with 47% graphic)
|
||||
tl.to('[data-composition-id="intro"] .title-card', {
|
||||
x: '-120%',
|
||||
opacity: 0,
|
||||
duration: 0.6,
|
||||
ease: 'power2.in'
|
||||
}, 1.8);
|
||||
tl.to(
|
||||
'[data-composition-id="intro"] .title-card',
|
||||
{
|
||||
x: "-120%",
|
||||
opacity: 0,
|
||||
duration: 0.6,
|
||||
ease: "power2.in",
|
||||
},
|
||||
1.8,
|
||||
);
|
||||
|
||||
window.__timelines["intro"] = tl;
|
||||
})();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# HyperFrames Design Review
|
||||
|
||||
## First Impression
|
||||
|
||||
This looks like a "warm and cozy" template that's trying too hard to be organic and ends up feeling like a corporate HR presentation from 2018. The "grain" is a lazy attempt at personality, and the layout is a chaotic mess of shifting boxes that lack any real editorial rhythm.
|
||||
|
||||
---
|
||||
@@ -8,18 +9,21 @@ This looks like a "warm and cozy" template that's trying too hard to be organic
|
||||
## CRITICAL Design Failures
|
||||
|
||||
### The "Drunken" A-Roll Framing
|
||||
|
||||
**Where:** `index.html` (GSAP timeline)
|
||||
**What's wrong:** The video is constantly shifting, scaling, and sliding around the screen like it's trying to escape the viewer. At one point it's at `x: 1100`, then `x: 600`, then `y: 750`, then `x: 1320`.
|
||||
**What's wrong:** The video is constantly shifting, scaling, and sliding around the screen like it's trying to escape the viewer. At one point it's at `x: 1100`, then `x: 600`, then `y: 750`, then `x: 1320`.
|
||||
**Why it matters:** It’s physically nauseating. Instead of creating a dynamic layout, you've created a composition that feels unstable. The viewer's eyes never know where to settle because the primary subject (the speaker) is in a state of perpetual motion for no reason.
|
||||
**Fix it:** Pick two or three solid "anchor" layouts (e.g., Left-Third, Right-Third, Center-Full) and snap between them with intent. Stop the slow, aimless drifting.
|
||||
|
||||
### The "Safety First" Color Palette
|
||||
|
||||
**Where:** `compositions/intro.html`, `compositions/graphics.html`
|
||||
**What's wrong:** Forest Green (`#3B5E3A`), Ochre (`#CC8832`), and Terracotta (`#C45D3E`) on a Cream background. It’s the "Earth Tones Starter Pack." It’s safe, it’s boring, and it has zero energy for a video about "Editor Agents" and "Motion Graphics."
|
||||
**Why it matters:** There is no visual "pop." The colors are so muted they bleed into each other, making the graphics feel heavy and dated rather than modern and sharp.
|
||||
**Fix it:** Introduce a high-contrast accent color or lean harder into a monochromatic sophisticated look. Right now, it looks like a brochure for a national park.
|
||||
|
||||
### Caption Box Suffocation
|
||||
|
||||
**Where:** `compositions/captions.html`
|
||||
**What's wrong:** The caption box has a fixed `padding: 12px 32px` and a `min-width: 100px`, but the text inside is a massive `48px` bold Outfit. When the text gets long, it’s going to hit the edges of that box and look like it's trying to burst out.
|
||||
**Why it matters:** It lacks "breathing room." Good typography needs negative space to feel premium. This feels cramped and amateur.
|
||||
@@ -30,11 +34,13 @@ This looks like a "warm and cozy" template that's trying too hard to be organic
|
||||
## Design Improvements
|
||||
|
||||
### The "Grain" is a Lie
|
||||
|
||||
**Where:** `index.html` (`.grain-texture`)
|
||||
**The problem:** You’re using a static PNG pattern (`natural-paper.png`) and jittering it at `0.15` opacity. It doesn't look like film grain; it looks like the screen is dirty.
|
||||
**Make it better:** Use a real SVG noise filter or a higher-frequency noise. If you want "Warm Grain," make it feel like a texture, not a CSS glitch.
|
||||
|
||||
### Robotic Graphic Entrances
|
||||
|
||||
**Where:** `compositions/graphics.html`
|
||||
**The problem:** Every single graphic uses the exact same `back.out(1.7)` ease. It’s the "My First GSAP Animation" preset.
|
||||
**Make it better:** Vary the entrance logic. Maybe the pill slides in, the circle expands from the center, and the rectangle fades with a staggered text reveal. Giving everything the same "bounce" makes the whole video feel repetitive by the 5-second mark.
|
||||
@@ -44,6 +50,7 @@ This looks like a "warm and cozy" template that's trying too hard to be organic
|
||||
## What Actually Works
|
||||
|
||||
### Typography Choice
|
||||
|
||||
The use of **Outfit** is actually a decent choice. It’s a clean, geometric sans-serif that bridges the gap between "tech" and "friendly." The weights are used correctly to create some semblance of hierarchy in the intro, even if the rest of the design fails it.
|
||||
|
||||
---
|
||||
|
||||
@@ -1,195 +1,281 @@
|
||||
<!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>Warm Grain - Editor Agent</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: #F5F0E0; /* Cream background */
|
||||
font-family: 'Outfit', 'Lexend', sans-serif;
|
||||
}
|
||||
body,
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background-color: #f5f0e0; /* Cream background */
|
||||
font-family: "Outfit", "Lexend", sans-serif;
|
||||
}
|
||||
|
||||
#main-composition {
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
}
|
||||
#main-composition {
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Paper texture and Grain overlay */
|
||||
#grain-overlay-comp {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 100;
|
||||
}
|
||||
/* Paper texture and Grain overlay */
|
||||
#grain-overlay-comp {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
/* Grain animation */
|
||||
@keyframes grain-noise {
|
||||
0%, 100% { transform: translate(0, 0); }
|
||||
10% { transform: translate(-5%, -5%); }
|
||||
20% { transform: translate(-10%, 5%); }
|
||||
30% { transform: translate(5%, -10%); }
|
||||
40% { transform: translate(-5%, 15%); }
|
||||
50% { transform: translate(-10%, 5%); }
|
||||
60% { transform: translate(15%, 0); }
|
||||
70% { transform: translate(0, 10%); }
|
||||
80% { transform: translate(-15%, 0); }
|
||||
90% { transform: translate(10%, 5%); }
|
||||
/* Grain animation */
|
||||
@keyframes grain-noise {
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
10% {
|
||||
transform: translate(-5%, -5%);
|
||||
}
|
||||
20% {
|
||||
transform: translate(-10%, 5%);
|
||||
}
|
||||
30% {
|
||||
transform: translate(5%, -10%);
|
||||
}
|
||||
40% {
|
||||
transform: translate(-5%, 15%);
|
||||
}
|
||||
50% {
|
||||
transform: translate(-10%, 5%);
|
||||
}
|
||||
60% {
|
||||
transform: translate(15%, 0);
|
||||
}
|
||||
70% {
|
||||
transform: translate(0, 10%);
|
||||
}
|
||||
80% {
|
||||
transform: translate(-15%, 0);
|
||||
}
|
||||
90% {
|
||||
transform: translate(10%, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
.grain-texture {
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: url('https://www.transparenttextures.com/patterns/natural-paper.png');
|
||||
opacity: 0.15;
|
||||
animation: grain-noise 0.5s steps(1) infinite;
|
||||
}
|
||||
.grain-texture {
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: url("https://www.transparenttextures.com/patterns/natural-paper.png");
|
||||
opacity: 0.15;
|
||||
animation: grain-noise 0.5s steps(1) infinite;
|
||||
}
|
||||
|
||||
#a-roll {
|
||||
position: absolute;
|
||||
border-radius: 16px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||
}
|
||||
#a-roll {
|
||||
position: absolute;
|
||||
border-radius: 16px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.comp-layer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
.comp-layer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main-composition" data-composition-id="main-video" data-width="1920" data-height="1080" data-duration="17">
|
||||
|
||||
<!-- Background Layer -->
|
||||
<div id="grain-overlay-comp" data-composition-id="grain-overlay" data-width="1920" data-height="1080" data-duration="17" data-track-index="100">
|
||||
<div class="grain-texture"></div>
|
||||
<script>
|
||||
const grainTl = gsap.timeline({ paused: true });
|
||||
window.__timelines["grain-overlay"] = grainTl;
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<!-- A-Roll Video -->
|
||||
<video id="a-roll"
|
||||
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/uploaded_assets/2111e840_0579531a2ffe4c3ea8295b42051fb394.mp4"
|
||||
data-start="0"
|
||||
data-duration="17"
|
||||
data-track-index="0">
|
||||
</video>
|
||||
|
||||
<!-- Compositions -->
|
||||
<div id="intro-layer" class="comp-layer"
|
||||
data-composition-id="intro"
|
||||
data-composition-src="compositions/intro.html"
|
||||
data-start="0"
|
||||
data-duration="2.5"
|
||||
data-track-index="1">
|
||||
</div>
|
||||
|
||||
<div id="graphics-layer" class="comp-layer"
|
||||
data-composition-id="graphics"
|
||||
data-composition-src="compositions/graphics.html"
|
||||
data-start="0"
|
||||
data-duration="17"
|
||||
data-track-index="2">
|
||||
</div>
|
||||
|
||||
<div id="captions-layer" class="comp-layer"
|
||||
data-composition-id="captions"
|
||||
data-composition-src="compositions/captions.html"
|
||||
data-start="0"
|
||||
data-duration="17"
|
||||
data-track-index="3">
|
||||
</div>
|
||||
|
||||
<!-- SFX -->
|
||||
<audio id="sfx-swipe-1" src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/generated_assets/3af40f3b_386326216dcf4956984e4c1c25663cdd.mp3" data-start="1.8" data-duration="1" data-track-index="4"></audio>
|
||||
<audio id="sfx-swipe-2" src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/generated_assets/3af40f3b_386326216dcf4956984e4c1c25663cdd.mp3" data-start="4.6" data-duration="1" data-track-index="4"></audio>
|
||||
<audio id="sfx-swipe-3" src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/generated_assets/3af40f3b_386326216dcf4956984e4c1c25663cdd.mp3" data-start="8.8" data-duration="1" data-track-index="4"></audio>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div
|
||||
id="main-composition"
|
||||
data-composition-id="main-video"
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
data-duration="17"
|
||||
>
|
||||
<!-- Background Layer -->
|
||||
<div
|
||||
id="grain-overlay-comp"
|
||||
data-composition-id="grain-overlay"
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
data-duration="17"
|
||||
data-track-index="100"
|
||||
>
|
||||
<div class="grain-texture"></div>
|
||||
<script>
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
|
||||
// A-Roll Framing Strategy
|
||||
// 1. 0s-1.8s: Intro scale up from small (60%) to medium (80%) - Shifted right slightly to clear speaker card
|
||||
// 2. 1.8s-4.6s: Grid view / Shift Left (x: 600, scale: 70%) for 47% graphic
|
||||
// 3. 4.6s-8.8s: Shift Center-Bottom (y: 800, scale: 70%) for 62% graphic (top)
|
||||
// 4. 8.8s-14s: Shift Right (x: 1320, scale: 75%) for Editing Skills graphic (left)
|
||||
// 5. 14s-17s: Final Reveal (Center, scale: 100%)
|
||||
|
||||
// Initial state
|
||||
gsap.set('#a-roll', { x: 1100, y: 540, xPercent: -50, yPercent: -50, width: 1920 * 0.6, height: 1080 * 0.6 });
|
||||
|
||||
// 1. Intro Scale Up (0s - 1.8s)
|
||||
tl.to('#a-roll', {
|
||||
x: 1200,
|
||||
width: 1920 * 0.8,
|
||||
height: 1080 * 0.8,
|
||||
duration: 1.8,
|
||||
ease: "power2.inOut"
|
||||
}, 0);
|
||||
|
||||
// 2. Moment 1: 47% Graphic Trigger (1.8s) - Shift Left
|
||||
tl.to('#a-roll', {
|
||||
x: 600,
|
||||
y: 540,
|
||||
width: 1920 * 0.7,
|
||||
height: 1080 * 0.7,
|
||||
duration: 0.5,
|
||||
ease: "power2.inOut"
|
||||
}, 1.8);
|
||||
|
||||
// 3. Moment 2: 62% Graphic Trigger (4.6s) - Shift Center-Bottom
|
||||
tl.to('#a-roll', {
|
||||
x: 960,
|
||||
y: 750,
|
||||
width: 1920 * 0.7,
|
||||
height: 1080 * 0.7,
|
||||
duration: 0.5,
|
||||
ease: "power2.inOut"
|
||||
}, 4.6);
|
||||
|
||||
// 4. Moment 3: Editing Skills Trigger (8.8s) - Shift Right
|
||||
tl.to('#a-roll', {
|
||||
x: 1320,
|
||||
y: 540,
|
||||
width: 1920 * 0.75,
|
||||
height: 1080 * 0.75,
|
||||
duration: 0.5,
|
||||
ease: "power2.inOut"
|
||||
}, 8.8);
|
||||
|
||||
// 5. Final Reveal (14s - 17s)
|
||||
tl.to('#a-roll', {
|
||||
x: 960,
|
||||
y: 540,
|
||||
width: 1920 * 1.0,
|
||||
height: 1080 * 1.0,
|
||||
duration: 1.0,
|
||||
ease: "power2.inOut"
|
||||
}, 14);
|
||||
|
||||
window.__timelines["main-video"] = tl;
|
||||
const grainTl = gsap.timeline({ paused: true });
|
||||
window.__timelines["grain-overlay"] = grainTl;
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<!-- A-Roll Video -->
|
||||
<video
|
||||
id="a-roll"
|
||||
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/uploaded_assets/2111e840_0579531a2ffe4c3ea8295b42051fb394.mp4"
|
||||
data-start="0"
|
||||
data-duration="17"
|
||||
data-track-index="0"
|
||||
></video>
|
||||
|
||||
<!-- Compositions -->
|
||||
<div
|
||||
id="intro-layer"
|
||||
class="comp-layer"
|
||||
data-composition-id="intro"
|
||||
data-composition-src="compositions/intro.html"
|
||||
data-start="0"
|
||||
data-duration="2.5"
|
||||
data-track-index="1"
|
||||
></div>
|
||||
|
||||
<div
|
||||
id="graphics-layer"
|
||||
class="comp-layer"
|
||||
data-composition-id="graphics"
|
||||
data-composition-src="compositions/graphics.html"
|
||||
data-start="0"
|
||||
data-duration="17"
|
||||
data-track-index="2"
|
||||
></div>
|
||||
|
||||
<div
|
||||
id="captions-layer"
|
||||
class="comp-layer"
|
||||
data-composition-id="captions"
|
||||
data-composition-src="compositions/captions.html"
|
||||
data-start="0"
|
||||
data-duration="17"
|
||||
data-track-index="3"
|
||||
></div>
|
||||
|
||||
<!-- SFX -->
|
||||
<audio
|
||||
id="sfx-swipe-1"
|
||||
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/generated_assets/3af40f3b_386326216dcf4956984e4c1c25663cdd.mp3"
|
||||
data-start="1.8"
|
||||
data-duration="1"
|
||||
data-track-index="4"
|
||||
></audio>
|
||||
<audio
|
||||
id="sfx-swipe-2"
|
||||
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/generated_assets/3af40f3b_386326216dcf4956984e4c1c25663cdd.mp3"
|
||||
data-start="4.6"
|
||||
data-duration="1"
|
||||
data-track-index="4"
|
||||
></audio>
|
||||
<audio
|
||||
id="sfx-swipe-3"
|
||||
src="https://gen-os-static.s3.us-east-2.amazonaws.com/astral_assets/generated_assets/3af40f3b_386326216dcf4956984e4c1c25663cdd.mp3"
|
||||
data-start="8.8"
|
||||
data-duration="1"
|
||||
data-track-index="4"
|
||||
></audio>
|
||||
|
||||
<script>
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
|
||||
// A-Roll Framing Strategy
|
||||
// 1. 0s-1.8s: Intro scale up from small (60%) to medium (80%) - Shifted right slightly to clear speaker card
|
||||
// 2. 1.8s-4.6s: Grid view / Shift Left (x: 600, scale: 70%) for 47% graphic
|
||||
// 3. 4.6s-8.8s: Shift Center-Bottom (y: 800, scale: 70%) for 62% graphic (top)
|
||||
// 4. 8.8s-14s: Shift Right (x: 1320, scale: 75%) for Editing Skills graphic (left)
|
||||
// 5. 14s-17s: Final Reveal (Center, scale: 100%)
|
||||
|
||||
// Initial state
|
||||
gsap.set("#a-roll", {
|
||||
x: 1100,
|
||||
y: 540,
|
||||
xPercent: -50,
|
||||
yPercent: -50,
|
||||
width: 1920 * 0.6,
|
||||
height: 1080 * 0.6,
|
||||
});
|
||||
|
||||
// 1. Intro Scale Up (0s - 1.8s)
|
||||
tl.to(
|
||||
"#a-roll",
|
||||
{
|
||||
x: 1200,
|
||||
width: 1920 * 0.8,
|
||||
height: 1080 * 0.8,
|
||||
duration: 1.8,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
0,
|
||||
);
|
||||
|
||||
// 2. Moment 1: 47% Graphic Trigger (1.8s) - Shift Left
|
||||
tl.to(
|
||||
"#a-roll",
|
||||
{
|
||||
x: 600,
|
||||
y: 540,
|
||||
width: 1920 * 0.7,
|
||||
height: 1080 * 0.7,
|
||||
duration: 0.5,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
1.8,
|
||||
);
|
||||
|
||||
// 3. Moment 2: 62% Graphic Trigger (4.6s) - Shift Center-Bottom
|
||||
tl.to(
|
||||
"#a-roll",
|
||||
{
|
||||
x: 960,
|
||||
y: 750,
|
||||
width: 1920 * 0.7,
|
||||
height: 1080 * 0.7,
|
||||
duration: 0.5,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
4.6,
|
||||
);
|
||||
|
||||
// 4. Moment 3: Editing Skills Trigger (8.8s) - Shift Right
|
||||
tl.to(
|
||||
"#a-roll",
|
||||
{
|
||||
x: 1320,
|
||||
y: 540,
|
||||
width: 1920 * 0.75,
|
||||
height: 1080 * 0.75,
|
||||
duration: 0.5,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
8.8,
|
||||
);
|
||||
|
||||
// 5. Final Reveal (14s - 17s)
|
||||
tl.to(
|
||||
"#a-roll",
|
||||
{
|
||||
x: 960,
|
||||
y: 540,
|
||||
width: 1920 * 1.0,
|
||||
height: 1080 * 1.0,
|
||||
duration: 1.0,
|
||||
ease: "power2.inOut",
|
||||
},
|
||||
14,
|
||||
);
|
||||
|
||||
window.__timelines["main-video"] = tl;
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user