feat(remotion): Instagram channel-promo template + taste system + design-quality kit
The reference-round workflow, run end to end for a real template: Taste system (how we learn the user's taste, persisted): - references/TASTE_PROFILE.md (living design contract) + references/README.md (the daily loop) + a "reference round" stage in docs/TEMPLATE_BRIEF.md (provide refs or I suggest+mock directions). Design-quality before/after: - HeroDemo — the fix recipe vs the faint default: layered-depth background, a proper big video type scale, and a bold composed focal object. (Backgrounds were naked, text too small, scenes had no objects.) - YaldaSofreh3D + IGPromoDirections + IGProfileMock — reference-match proofs (low-poly 3D, 3 IG-promo style directions, the realistic IG-light page). Instagram channel-promo template (the deliverable — a flexible 5-scene FlexStory): - igkit + 5 blocks: IGIntro, IGProfile (realistic IG-light profile, scales to all aspects), IGFeed (post grid), IGStats (animated count-up), IGFollowCTA (Follow taps to "Following"). - FlexStory gains a `finish` toggle so the IG-light scenes render clean (no brand grade). INSTAGRAM_PROMO preset + 3 aspect comps in Root. Verified: a still of every scene at 9:16 renders clean; full preview MP4 rendering. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,11 +2,15 @@ import { Composition } from "remotion";
|
||||
import { ASPECTS } from "./lib/aspect";
|
||||
import { TEMPLATES } from "./templates";
|
||||
import { Three3DTest } from "./compositions/Three3DTest";
|
||||
import { YaldaSofreh3D } from "./compositions/YaldaSofreh3D";
|
||||
import { HeroDemo } from "./compositions/HeroDemo";
|
||||
import { IGPromoDirections, igPromoSchema } from "./compositions/IGPromoDirections";
|
||||
import { IGProfileMock } from "./compositions/IGProfileMock";
|
||||
import { AssetSheet } from "./compositions/AssetSheet";
|
||||
import { StoryScenes, STORY_SCENES_DURATION } from "./compositions/StoryScenes";
|
||||
import { FlexStory, flexStorySchema, flexStoryDefaults, calcFlexStoryMetadata } from "./compositions/FlexStory";
|
||||
import { LogoMotion3D, logoMotion3DSchema, logoMotion3DDefaults } from "./compositions/LogoMotion3D";
|
||||
import { CHARACTER_JOURNEY } from "./scenes/presets";
|
||||
import { CHARACTER_JOURNEY, INSTAGRAM_PROMO } from "./scenes/presets";
|
||||
import {
|
||||
IlluminatedCircles,
|
||||
illuminatedCirclesSchema,
|
||||
@@ -133,6 +137,51 @@ export const RemotionRoot: React.FC = () => {
|
||||
height={720}
|
||||
/>
|
||||
|
||||
{/* Design-quality before/after demo (rich bg + big type + bold object) */}
|
||||
{ASPECTS.map((a) => (
|
||||
<Composition
|
||||
key={`HeroDemo-${a.id}`}
|
||||
id={`HeroDemo-${a.id}`}
|
||||
component={HeroDemo}
|
||||
durationInFrames={5 * FPS}
|
||||
fps={FPS}
|
||||
width={a.width}
|
||||
height={a.height}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Instagram profile mock — realistic light-theme page (gate still) */}
|
||||
<Composition
|
||||
id="IGProfileMock"
|
||||
component={IGProfileMock}
|
||||
durationInFrames={150}
|
||||
fps={FPS}
|
||||
width={1080}
|
||||
height={1920}
|
||||
/>
|
||||
|
||||
{/* Instagram promo — reference round (3 style directions to pick from) */}
|
||||
<Composition
|
||||
id="IGPromoDir"
|
||||
component={IGPromoDirections}
|
||||
durationInFrames={150}
|
||||
fps={FPS}
|
||||
width={1080}
|
||||
height={1920}
|
||||
schema={igPromoSchema}
|
||||
defaultProps={{ variant: "A" as const }}
|
||||
/>
|
||||
|
||||
{/* Low-poly Yalda sofreh — reference-match challenge */}
|
||||
<Composition
|
||||
id="YaldaSofreh3D"
|
||||
component={YaldaSofreh3D}
|
||||
durationInFrames={150}
|
||||
fps={30}
|
||||
width={1080}
|
||||
height={1080}
|
||||
/>
|
||||
|
||||
{/* Dev preview: vendored CC0 character library (not a customer template) */}
|
||||
<Composition
|
||||
id="AssetSheet"
|
||||
@@ -189,6 +238,22 @@ export const RemotionRoot: React.FC = () => {
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* InstagramPromo — "follow our channel" template (realistic IG-light page). */}
|
||||
{ASPECTS.map((a) => (
|
||||
<Composition
|
||||
key={`InstagramPromo-${a.id}`}
|
||||
id={`InstagramPromo-${a.id}`}
|
||||
component={FlexStory}
|
||||
durationInFrames={18 * FPS}
|
||||
fps={FPS}
|
||||
width={a.width}
|
||||
height={a.height}
|
||||
schema={flexStorySchema}
|
||||
defaultProps={INSTAGRAM_PROMO}
|
||||
calculateMetadata={calcFlexStoryMetadata}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Branded templates — each registered in all three aspects. A template may
|
||||
supply a dedicated component per aspect (componentsByAspect) when its
|
||||
design differs structurally; otherwise the shared `component` adapts
|
||||
|
||||
Reference in New Issue
Block a user