refactor: bundle the whole template suite under flat-artist/ + fix references
flat-artist is now the single container: all 16 template skills + the R&D references/ moved inside flat-artist/. Cross-references updated — the orchestrator points to bundled `<name>/SKILL.md`, sub-skills point to `../<name>/SKILL.md`, and the R&D report path is relative. README catalog updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ Install any skill by copying its folder into `~/.claude/skills/`.
|
||||
| Skill | Description |
|
||||
|---|---|
|
||||
| [soroush-cicd](./soroush-cicd/SKILL.md) | CI/CD pipeline method using self-hosted Gitea + Nexus mirror. Covers workflow design, Docker deploy patterns, port safety, DB backup before deploy, rollback tagging, and lessons from real production incidents on draletaha.ir. Trigger: "my ci/cd method", "add CI/CD", "deploy to gitea". |
|
||||
| [flat-artist](./flat-artist/SKILL.md) | **Master entry point** for creating FlatRender video templates with Remotion + Three.js — a professional motion-design pipeline to a Renderforest/AE bar. **Bundles the whole template-creation suite inside its folder**: 16 sub-skills (`flat-artist/<name>/SKILL.md`) — design-styles, character-design, aspect-ratios, template-composition, sound-effects, music-picker, template-catalog, svg-colors, persian-fonts, flatrender-template-seo, motion-design-principles, scene-transitions, kinetic-typography, video-hooks, particles-and-effects, asset-sourcing — plus a design/motion R&D report (`flat-artist/references/design-motion-rnd.md`). Persian-first. Trigger: "Flat Artist", "start/design a flatrender template". |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+24
-21
@@ -19,9 +19,12 @@ and apply the sub-skills — never ship "basic". Stack: `services/remotion/` (Re
|
||||
`@remotion/three`, R3F v9, `gl="angle"`). Persian (fa) is canonical; English mirrors it 1:1.
|
||||
|
||||
## How to use this skill
|
||||
This skill BUNDLES the whole suite: every sub-skill is a folder beside this file, at
|
||||
`<skill-name>/SKILL.md` (relative to this `flat-artist/SKILL.md`). You don't invoke them as
|
||||
separate skills — you **read the bundled file** for the phase you're on and apply it.
|
||||
1. Read this file's pipeline + rules.
|
||||
2. At each phase, **invoke the named sub-skill** with the Skill tool (or apply its guidance if already loaded). They live in the Gitea `AISkills` repo and in this project's `.claude/skills/`.
|
||||
3. The deep R&D reference is `AISkills/references/design-motion-rnd.md` (trends, craft, asset pipeline, masterpiece + platform playbook) — consult it for art direction and the masterpiece bar.
|
||||
2. At each phase, open the bundled sub-skill at **`<skill-name>/SKILL.md`** (e.g. `motion-design-principles/SKILL.md`) and apply it.
|
||||
3. The deep R&D reference is **`references/design-motion-rnd.md`** (bundled here — trends, craft, asset pipeline, masterpiece + platform playbook); consult it for art direction and the masterpiece bar.
|
||||
|
||||
## Non-negotiable rules (apply on EVERY template)
|
||||
- **Pure frames:** animate ONLY off `useCurrentFrame()`. Never `useFrame` (R3F), `Math.random()`, `Date.now()`, `setState`/`useEffect`-driven motion. Determinism via `rand(i)` (`lib/anim.ts`).
|
||||
@@ -33,27 +36,27 @@ and apply the sub-skills — never ship "basic". Stack: `services/remotion/` (Re
|
||||
- **Vendored assets (Iran iron rule):** every asset committed into `services/remotion/public/` + `staticFile()`; NEVER a CDN URL at render. License firewall (CC0/commercial-ok, tracked in `assets.json`).
|
||||
- **Finish it:** a masterpiece = the 8 layers below, not one big move. Render → LOOK → refine.
|
||||
|
||||
## The pipeline (work in order; invoke the skill named at each step)
|
||||
## The pipeline (work in order; read the bundled skill named at each step)
|
||||
|
||||
| # | Phase | Apply skill |
|
||||
|---|---|---|
|
||||
| 0 | **Scope & storyboard** — pick the template TYPE/pattern; confirm a storyboard with the user before building anything character- or scene-heavy | `remotion-template-catalog` |
|
||||
| 1 | **Art direction** — choose ONE coherent style + palette from current trends | `remotion-design-styles` + R&D report |
|
||||
| 2 | **Hook** — design the scroll-stopping first 1–3s (it's the cover frame) | `video-hooks` |
|
||||
| 3 | **Characters** (if any) — build/rig from SVG or 3D primitives | `remotion-character-design` |
|
||||
| 0 | **Scope & storyboard** — pick the template TYPE/pattern; confirm a storyboard with the user before building anything character- or scene-heavy | `remotion-template-catalog/SKILL.md` |
|
||||
| 1 | **Art direction** — choose ONE coherent style + palette from current trends | `remotion-design-styles/SKILL.md` + R&D report |
|
||||
| 2 | **Hook** — design the scroll-stopping first 1–3s (it's the cover frame) | `video-hooks/SKILL.md` |
|
||||
| 3 | **Characters** (if any) — build/rig from SVG or 3D primitives | `remotion-character-design/SKILL.md` |
|
||||
| 4 | **Build the composition** — lib helpers + `three-kit` for 3D | (this skill) |
|
||||
| 5 | **Motion** — easing/timing/stagger/secondary motion (the foundation) | `motion-design-principles` |
|
||||
| 6 | **Kinetic type** — animate the hero/caption text (Persian word-split) | `kinetic-typography` |
|
||||
| 7 | **Transitions** — scene-to-scene choreography, seamless | `scene-transitions` |
|
||||
| 8 | **Effects** — grain, bokeh, light-leaks, sparkles, glow, vignette (deterministic) | `particles-and-effects` |
|
||||
| 9 | **Aspect re-flow** — make it truly fit 16:9/1:1/9:16 | `remotion-aspect-ratios` |
|
||||
| 10 | **Composition & elements** — hierarchy, logo/image/copy, reveal pacing | `remotion-template-composition` |
|
||||
| 11 | **Color / live recolor** — wire color props + SVG color preview | `remotion-svg-colors` |
|
||||
| 12 | **Fonts** — pick Persian-first type by role | `persian-fonts` |
|
||||
| 13 | **Assets / footage** — source, license, prepare, composite | `asset-sourcing` |
|
||||
| 14 | **Music + SFX** — beat-sync reveals, place SFX, duck | `remotion-music-picker` + `remotion-sound-effects` |
|
||||
| 5 | **Motion** — easing/timing/stagger/secondary motion (the foundation) | `motion-design-principles/SKILL.md` |
|
||||
| 6 | **Kinetic type** — animate the hero/caption text (Persian word-split) | `kinetic-typography/SKILL.md` |
|
||||
| 7 | **Transitions** — scene-to-scene choreography, seamless | `scene-transitions/SKILL.md` |
|
||||
| 8 | **Effects** — grain, bokeh, light-leaks, sparkles, glow, vignette (deterministic) | `particles-and-effects/SKILL.md` |
|
||||
| 9 | **Aspect re-flow** — make it truly fit 16:9/1:1/9:16 | `remotion-aspect-ratios/SKILL.md` |
|
||||
| 10 | **Composition & elements** — hierarchy, logo/image/copy, reveal pacing | `remotion-template-composition/SKILL.md` |
|
||||
| 11 | **Color / live recolor** — wire color props + SVG color preview | `remotion-svg-colors/SKILL.md` |
|
||||
| 12 | **Fonts** — pick Persian-first type by role | `persian-fonts/SKILL.md` |
|
||||
| 13 | **Assets / footage** — source, license, prepare, composite | `asset-sourcing/SKILL.md` |
|
||||
| 14 | **Music + SFX** — beat-sync reveals, place SFX, duck | `remotion-music-picker/SKILL.md` + `remotion-sound-effects/SKILL.md` |
|
||||
| 15 | **QA — masterpiece gate** — the 8 layers + pre-ship checklist (below) | (this skill) |
|
||||
| 16 | **SEO & taxonomy** — category, tags, keywords, slug, copy, related | `flatrender-template-seo` |
|
||||
| 16 | **SEO & taxonomy** — category, tags, keywords, slug, copy, related | `flatrender-template-seo/SKILL.md` |
|
||||
| 17 | **Ship** — render 3 thumbnails + preview, seed, deploy (copy assets into the running container + restart so Next re-scans `public/`) | (this skill) |
|
||||
|
||||
## The masterpiece bar (8 production-value layers — finish ALL)
|
||||
@@ -74,13 +77,13 @@ and apply the sub-skills — never ship "basic". Stack: `services/remotion/` (Re
|
||||
- [ ] Subtle grain/vignette; frame feels alive; (audio: beat-synced + ducked if present).
|
||||
- [ ] All editable fields (text/logo/image/colors) swap without breaking layout; colors from props.
|
||||
- [ ] Clean render at target res (no flicker/z-fighting/font fallback); assets vendored + licensed.
|
||||
- [ ] Category/tags/keywords/slug + fa+en copy set (`flatrender-template-seo`).
|
||||
- [ ] Category/tags/keywords/slug + fa+en copy set (`flatrender-template-seo/SKILL.md`).
|
||||
|
||||
## Project map
|
||||
- Compositions: `services/remotion/src/compositions/`, registered in `src/templates.tsx` (`TemplateDef`, all 3 aspects).
|
||||
- Helpers: `lib/anim.ts`, `lib/aspect.ts` (`useLayout`/`pick`), `lib/branding.ts` (`colorSchema`/`BRAND`), `lib/fonts.ts` (`FONT`), `lib/three-kit.tsx`.
|
||||
- Seed: `scripts/seed_remotion_templates.py` (containers/projects/scenes/colors + `MEDIA` for image fields).
|
||||
- Render checks: `npx remotion still src/index.ts "<Comp>-16x9|1x1|9x16" out/x.png --frame=NN`.
|
||||
- Skills + R&D: Gitea `AISkills` repo (`references/design-motion-rnd.md`).
|
||||
- Bundled here: each sub-skill at `<name>/SKILL.md`; the deep R&D at `references/design-motion-rnd.md`.
|
||||
|
||||
Related (the suite this orchestrates): `remotion-template-catalog`, `remotion-design-styles`, `video-hooks`, `remotion-character-design`, `motion-design-principles`, `kinetic-typography`, `scene-transitions`, `particles-and-effects`, `remotion-aspect-ratios`, `remotion-template-composition`, `remotion-svg-colors`, `persian-fonts`, `asset-sourcing`, `remotion-music-picker`, `remotion-sound-effects`, `flatrender-template-seo`.
|
||||
Bundled sub-skills (read each at its `SKILL.md`): `remotion-template-catalog/SKILL.md`, `remotion-design-styles/SKILL.md`, `video-hooks/SKILL.md`, `remotion-character-design/SKILL.md`, `motion-design-principles/SKILL.md`, `kinetic-typography/SKILL.md`, `scene-transitions/SKILL.md`, `particles-and-effects/SKILL.md`, `remotion-aspect-ratios/SKILL.md`, `remotion-template-composition/SKILL.md`, `remotion-svg-colors/SKILL.md`, `persian-fonts/SKILL.md`, `asset-sourcing/SKILL.md`, `remotion-music-picker/SKILL.md`, `remotion-sound-effects/SKILL.md`, `flatrender-template-seo/SKILL.md`.
|
||||
|
||||
@@ -92,4 +92,4 @@ Sidecar `.license.txt` next to AI assets (prompt + tool + date) and paid receipt
|
||||
- [ ] Ken-Burns overscans (start scale ≥ 1.05) and `objectFit:cover` crops cleanly in 16:9 / 1:1 / 9:16 with subject in frame.
|
||||
- [ ] Re-render twice → identical (deterministic; nothing pulled from network/random/date).
|
||||
|
||||
Related: `remotion-design-styles`, `remotion-template-composition`, `remotion-aspect-ratios`, `remotion-character-design`, `remotion-svg-colors`, `remotion-music-picker`, `remotion-sound-effects`, `persian-fonts`, `flatrender-template-seo`.
|
||||
Related: `../remotion-design-styles/SKILL.md`, `../remotion-template-composition/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../remotion-character-design/SKILL.md`, `../remotion-svg-colors/SKILL.md`, `../remotion-music-picker/SKILL.md`, `../remotion-sound-effects/SKILL.md`, `../persian-fonts/SKILL.md`, `../flatrender-template-seo/SKILL.md`.
|
||||
@@ -20,8 +20,8 @@ template *actually is*, not what you wish it ranked for. **fa is canonical; en m
|
||||
- You run/extend `scripts/seed_remotion_templates.py` (which currently leaves SEO + taxonomy EMPTY — see below).
|
||||
- You publish (`is_published = true`) and need the template to be findable and well-presented.
|
||||
|
||||
Cross-reference: `remotion-template-catalog` (template TYPE → pattern), `remotion-template-composition`
|
||||
(what's editable, used to write "what you can customize"), `persian-fonts` (RTL copy & Persian numerals).
|
||||
Cross-reference: `../remotion-template-catalog/SKILL.md` (template TYPE → pattern), `../remotion-template-composition/SKILL.md`
|
||||
(what's editable, used to write "what you can customize"), `../persian-fonts/SKILL.md` (RTL copy & Persian numerals).
|
||||
|
||||
## The real data model (use these exact names — do not invent fields)
|
||||
|
||||
@@ -66,7 +66,7 @@ Template = `content.project_containers`. Admin sets via `TemplatesAdmin.tsx` →
|
||||
Run this for every template, in order. Each step feeds the next.
|
||||
|
||||
**0. Read the design + content + usability.** What does it output (format)? What's editable (text/colors/
|
||||
logo/images/music — from `remotion-template-composition`)? Who hires it and when? 2D or 3D (real Remotion
|
||||
logo/images/music — from `../remotion-template-composition/SKILL.md`)? Who hires it and when? 2D or 3D (real Remotion
|
||||
build: SVG vs `@remotion/three`)? Which aspects exist (16:9 / 1:1 / 9:16 child projects)?
|
||||
|
||||
**1. Category — pick exactly ONE primary.** Category = the *output format*, never the occasion/industry.
|
||||
@@ -112,7 +112,7 @@ label pack-mates «از همین مجموعه».
|
||||
## fa / en parity & RTL rules
|
||||
- Fill fa first, then en as a faithful mirror. Two self-consistent pages — never a Persian page with an
|
||||
English title. Same template id; localized labels resolve per current locale.
|
||||
- Persian uses Vazirmatn / RTL (see `persian-fonts`); use Persian digits in user-facing copy; don't fight the
|
||||
- Persian uses Vazirmatn / RTL (see `../persian-fonts/SKILL.md`); use Persian digits in user-facing copy; don't fight the
|
||||
`[dir="rtl"]` block. Tag/category *slugs* stay latin for stability; *display names* are localized.
|
||||
- hreflang fa↔en + x-default is the right target even though the detail page doesn't emit it yet — flag the gap.
|
||||
|
||||
@@ -13,7 +13,7 @@ Every value is a pure function of `useCurrentFrame()`. **Never** `useFrame`, `Ma
|
||||
## Persian / RTL — get this right first (it's an Iran-facing product)
|
||||
- **Split by WORD, not character.** Persian script is connected/cursive — splitting on chars shatters letterforms and joins. Latin char-reveals are fine; Persian is word- or line-only. A safe split is `text.split(/\s+/).filter(Boolean)` — this **preserves ZWNJ** (نیمفاصله, ``) inside words like «میشود» because ZWNJ is not whitespace. Never `.split("")` or `.replace(//g, …)` on Persian.
|
||||
- Every text node: `fontFamily: FONT` (Vazirmatn, from `lib/fonts.ts`), `direction: "rtl"`, align right or center. The existing `KineticQuote.tsx` hardcodes Georgia/serif + pixel sizes + no RTL — **do not copy that**; it's a Latin-only relic.
|
||||
- Persian needs weight (headings 700–900) and `lineHeight: 1.4–1.6`. Numerals: pick Persian (۱۲۳ via `toLocaleString('fa-IR')`) or Latin and stay consistent; prices/years are usually Persian digits. See `persian-fonts`.
|
||||
- Persian needs weight (headings 700–900) and `lineHeight: 1.4–1.6`. Numerals: pick Persian (۱۲۳ via `toLocaleString('fa-IR')`) or Latin and stay consistent; prices/years are usually Persian digits. See `../persian-fonts/SKILL.md`.
|
||||
- For RTL word reveals, the wrapping container does the ordering — keep `flexWrap: "wrap"` + `direction: "rtl"` and let words flow; don't manually reverse the array.
|
||||
|
||||
## Size & position from layout tokens, never pixels
|
||||
@@ -80,7 +80,7 @@ Micro pop 8–14f · word stagger 2–4f · standard reveal 18–28f · hero ent
|
||||
- Scrim or `textShadow: 0 0 vmin(20) rgba(0,0,0,.7)`, or a semi-transparent panel behind text.
|
||||
- Gradient text: `WebkitBackgroundClip: "text"`, transparent fill, plus a `drop-shadow` for edge separation.
|
||||
- Colors come from `colorSchema` props (`accentColor/secondaryColor/backgroundColor/textColor` via `lib/branding.ts`) — pass user hex through `mixHex`/`hexToRgba` so a garish value doesn't break the look. Never hardcode `#fff`.
|
||||
- Captions (TikTok/Reels/Shorts) = high-contrast white/yellow + black outline, lower-middle third, inside the tightest safe zone. See `remotion-aspect-ratios`.
|
||||
- Captions (TikTok/Reels/Shorts) = high-contrast white/yellow + black outline, lower-middle third, inside the tightest safe zone. See `../remotion-aspect-ratios/SKILL.md`.
|
||||
|
||||
## Checklist
|
||||
- [ ] Persian text split by WORD; ZWNJ preserved; `direction:"rtl"` + `fontFamily: FONT`.
|
||||
@@ -92,4 +92,4 @@ Micro pop 8–14f · word stagger 2–4f · standard reveal 18–28f · hero ent
|
||||
- [ ] A real hold sized to reading; longest Persian string doesn't overflow, shortest doesn't look empty.
|
||||
- [ ] Re-render twice → identical pixels (deterministic).
|
||||
|
||||
Related: `remotion-template-composition`, `persian-fonts`, `remotion-aspect-ratios`, `remotion-design-styles`, `remotion-svg-colors`, `remotion-sound-effects`, `remotion-music-picker`, `flatrender-template-seo`.
|
||||
Related: `../remotion-template-composition/SKILL.md`, `../persian-fonts/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../remotion-design-styles/SKILL.md`, `../remotion-svg-colors/SKILL.md`, `../remotion-sound-effects/SKILL.md`, `../remotion-music-picker/SKILL.md`, `../flatrender-template-seo/SKILL.md`.
|
||||
@@ -127,7 +127,7 @@ const L = useLayout();
|
||||
const stagger = L.pick(/*wide*/ 3, /*square*/ 4, /*tall*/ 5); // pick(wide, square, tall)
|
||||
const start = i * stagger;
|
||||
```
|
||||
Patterns: **cascade** (lists/features) · **center-out** (logo/hero rows: `delay = Math.abs(i - mid) * stagger`) · **deterministic random** (particles: `rand(i)` for delay/offset) · **beat-synced** (snap `start` to music beat frames — see `remotion-music-picker`). **One thing enters the eye at a time.**
|
||||
Patterns: **cascade** (lists/features) · **center-out** (logo/hero rows: `delay = Math.abs(i - mid) * stagger`) · **deterministic random** (particles: `rand(i)` for delay/offset) · **beat-synced** (snap `start` to music beat frames — see `../remotion-music-picker/SKILL.md`). **One thing enters the eye at a time.**
|
||||
|
||||
> `pick` is the standard per-aspect selector on `useLayout()`. If it isn't on `Layout` yet, add it in `aspect.ts`: `pick: <T,>(wide: T, square: T, tall: T): T => kind === "wide" ? wide : kind === "tall" ? tall : square,`
|
||||
|
||||
@@ -136,10 +136,10 @@ Drive every transform off `useCurrentFrame()` (deterministic under ANGLE) — **
|
||||
|
||||
## The pro workflow — 5 passes, IN ORDER
|
||||
Polishing before timing is locked wastes the most time.
|
||||
1. **Reference** — decide the feel before code; pick style (`remotion-design-styles`), type (`persian-fonts`), composition (`remotion-template-composition`), per-aspect rules (`remotion-aspect-ratios`). Write the beat list ("logo in → tagline → 3 features cascade → CTA → out").
|
||||
1. **Reference** — decide the feel before code; pick style (`../remotion-design-styles/SKILL.md`), type (`../persian-fonts/SKILL.md`), composition (`../remotion-template-composition/SKILL.md`), per-aspect rules (`../remotion-aspect-ratios/SKILL.md`). Write the beat list ("logo in → tagline → 3 features cascade → CTA → out").
|
||||
2. **Blocking** — every element at its final position with crude `interpolate` fades, no easing. Fix off-screen/cropping in all three aspects NOW.
|
||||
3. **Timing** — lock frame counts, stagger, beats, holds, transitions. Watch at full speed repeatedly. Mood lives here.
|
||||
4. **Polish** — swap linear for easing/springs; add anticipation + overshoot/settle, follow-through, secondary motion, arcs, squash/stretch; `StudioEffects` for 3D; wire SFX (`remotion-sound-effects`) + music sync (`remotion-music-picker`) to the locked frames.
|
||||
4. **Polish** — swap linear for easing/springs; add anticipation + overshoot/settle, follow-through, secondary motion, arcs, squash/stretch; `StudioEffects` for 3D; wire SFX (`../remotion-sound-effects/SKILL.md`) + music sync (`../remotion-music-picker/SKILL.md`) to the locked frames.
|
||||
5. **Review** — scrub frame-by-frame + full speed against the checklist below.
|
||||
|
||||
## Top amateur mistakes → fixes (review gate)
|
||||
@@ -164,4 +164,4 @@ Polishing before timing is locked wastes the most time.
|
||||
- [ ] One clear hero moment with the biggest motion; the eye always knows where to look.
|
||||
- [ ] Re-render twice → pixel-identical (deterministic).
|
||||
|
||||
Related: `remotion-design-styles`, `remotion-aspect-ratios`, `remotion-template-composition`, `remotion-character-design`, `remotion-sound-effects`, `remotion-music-picker`, `persian-fonts`, `flatrender-template-seo`.
|
||||
Related: `../remotion-design-styles/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../remotion-template-composition/SKILL.md`, `../remotion-character-design/SKILL.md`, `../remotion-sound-effects/SKILL.md`, `../remotion-music-picker/SKILL.md`, `../persian-fonts/SKILL.md`, `../flatrender-template-seo/SKILL.md`.
|
||||
@@ -103,7 +103,7 @@ Put shared FX in `src/lib/fx.tsx` so every template gets the same texture:
|
||||
Each takes `colorSchema` colors so the studio picker recolors the FX, and reads `useLayout()` for per-aspect count/size.
|
||||
|
||||
## Restraint — FX amplify a hero, they are not the show
|
||||
- One celebratory burst on the **hero moment**, not raining the whole video. Often **silence before** + confetti + sparkle SFX on the same frame (see `remotion-sound-effects`).
|
||||
- One celebratory burst on the **hero moment**, not raining the whole video. Often **silence before** + confetti + sparkle SFX on the same frame (see `../remotion-sound-effects/SKILL.md`).
|
||||
- Finishing texture (grain, vignette, drift) is *subtle and always-on*; spectacle (confetti, flare, big aberration) is *brief and on a beat*.
|
||||
- Don't stack 6 effects at full strength — that reads as a tool preset. Grain at 0.08, vignette at 0.5, aberration only at impacts.
|
||||
- All FX color from `colorSchema`; pass a user's garish hex through `mixHex(hex, background, 0.2)` so it doesn't blow out.
|
||||
@@ -117,4 +117,4 @@ Each takes `colorSchema` colors so the studio picker recolors the FX, and reads
|
||||
- [ ] FX colors read from `colorSchema`; a continuous camera drift keeps the frame alive.
|
||||
- [ ] 3D glow uses `emissive`+`toneMapped={false}` + `StudioEffects` (not hand-rolled bloom).
|
||||
|
||||
Related: `remotion-design-styles`, `remotion-character-design`, `remotion-aspect-ratios`, `remotion-template-composition`, `remotion-sound-effects`, `remotion-music-picker`, `remotion-svg-colors`, `persian-fonts`, `remotion-template-catalog`, `flatrender-template-seo`.
|
||||
Related: `../remotion-design-styles/SKILL.md`, `../remotion-character-design/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../remotion-template-composition/SKILL.md`, `../remotion-sound-effects/SKILL.md`, `../remotion-music-picker/SKILL.md`, `../remotion-svg-colors/SKILL.md`, `../persian-fonts/SKILL.md`, `../remotion-template-catalog/SKILL.md`, `../flatrender-template-seo/SKILL.md`.
|
||||
@@ -52,4 +52,4 @@ Pairing rule: one display face for the headline + Vazirmatn (or Shabnam) for eve
|
||||
## Licensing
|
||||
Prefer SIL OFL / free-for-commercial Persian fonts (Vazirmatn, Estedad, Shabnam, Sahel, Samim, Gandom, Morabba — most from the `font-store`/Google Persian sets are OFL). Verify each before shipping in an exported-video product; keep a license record.
|
||||
|
||||
Related: `remotion-template-composition`, `remotion-design-styles`.
|
||||
Related: `../remotion-template-composition/SKILL.md`, `../remotion-design-styles/SKILL.md`.
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
## 1) Design trends to adopt (each with a concrete how-to in our stack)
|
||||
|
||||
Every trend below survives all three aspects only if you anchor to safe-zone **percentages / `layout.vmin()`**, never absolute pixels. Read `remotion-aspect-ratios` before positioning anything.
|
||||
Every trend below survives all three aspects only if you anchor to safe-zone **percentages / `layout.vmin()`**, never absolute pixels. Read `../remotion-aspect-ratios/SKILL.md` before positioning anything.
|
||||
|
||||
### Typography (type is a first-class motion element, not a label)
|
||||
|
||||
@@ -114,11 +114,11 @@ Micro pop 8–14f · standard reveal 18–28f · hero entrance 28–40f · scene
|
||||
Drive every transform off `useCurrentFrame()` (deterministic under ANGLE). Rotation/orbit = `linear` (mechanical); entrances/landings = `spring` with high mass for weight. Let `StudioEffects` (bloom + DOF + vignette) do the cinematic polish in one component.
|
||||
|
||||
### The pro workflow (5 passes, IN ORDER — polishing before timing is locked wastes the most time)
|
||||
1. **Reference** — decide the feel before code; pull an AE template/Dribbble loop; pick style (`remotion-design-styles`), type (`persian-fonts`), composition (`remotion-template-composition`), per-aspect rules (`remotion-aspect-ratios`); write the beat list ("logo in → tagline → 3 features cascade → CTA → out").
|
||||
1. **Reference** — decide the feel before code; pull an AE template/Dribbble loop; pick style (`../remotion-design-styles/SKILL.md`), type (`../persian-fonts/SKILL.md`), composition (`../remotion-template-composition/SKILL.md`), per-aspect rules (`../remotion-aspect-ratios/SKILL.md`); write the beat list ("logo in → tagline → 3 features cascade → CTA → out").
|
||||
2. **Blocking** — every element on screen at final position with crude `interpolate` fades, no easing. Fix off-screen/cropping in all three aspects now.
|
||||
3. **Timing** — lock frame counts, stagger, beats, holds, transitions. Watch at full speed repeatedly. Mood lives here.
|
||||
4. **Polish** — swap linear for easing/springs; add anticipation+overshoot+settle, follow-through, secondary motion, arcs, squash/stretch; `StudioEffects` for 3D; wire SFX (`remotion-sound-effects`) and music sync (`remotion-music-picker`) to the locked frames.
|
||||
5. **Review** — scrub frame-by-frame + full speed. Nothing pops without an ease; nothing leaves slower than it arrived; the eye always knows where to look; reads in all three aspects; Persian RTL not clipped; colors from `colorSchema`; re-render twice → identical (deterministic). Then run `flatrender-template-seo`.
|
||||
4. **Polish** — swap linear for easing/springs; add anticipation+overshoot+settle, follow-through, secondary motion, arcs, squash/stretch; `StudioEffects` for 3D; wire SFX (`../remotion-sound-effects/SKILL.md`) and music sync (`../remotion-music-picker/SKILL.md`) to the locked frames.
|
||||
5. **Review** — scrub frame-by-frame + full speed. Nothing pops without an ease; nothing leaves slower than it arrived; the eye always knows where to look; reads in all three aspects; Persian RTL not clipped; colors from `colorSchema`; re-render twice → identical (deterministic). Then run `../flatrender-template-seo/SKILL.md`.
|
||||
|
||||
### Top amateur mistakes → fixes (review gate)
|
||||
Linear motion → ease/spring · no anticipation/overshoot → dip-then-launch / back bezier · everything on one frame → stagger · forgot `clamp` → clamp both ends · hardcoded 30fps → `useVideoConfig().fps` · `useFrame`/`random`/`Date.now` → `useCurrentFrame` + `rand` · pixel-hardcoded sizes → `vmin`/`unit` + branch on `isWide/isSquare/isTall` · over-animating → one idea per beat · no hold → real hold sized to reading · exit = entrance speed → exits sharper · dead holds → `sin` bob/breathe/shimmer · flat 3D lighting → `StudioLights` + floor shadows + `StudioEffects` · color hardcoded → read from props.
|
||||
@@ -142,7 +142,7 @@ The Iran environment punishes runtime dependencies. **All assets are vendored**
|
||||
- **Textures & overlays:** Poly Haven Textures (CC0), ambientCG (CC0); grain/light-leak/dust = CC0 video clips you screen-blend.
|
||||
- **HDRIs:** Poly Haven (1k–2k for render speed), ambientCG.
|
||||
- **3D (GLB):** Poly Haven Models (CC0, cleanest), Kenney.nl (CC0 low-poly), Khronos glTF samples, Sketchfab (**mixed — check each**, filter Downloadable + CC0/CC-BY). **Prefer GLB over glTF+separate-textures** (one file, no broken paths); Draco-compress with `gltf-pipeline -b`; keep low-poly for headless render speed.
|
||||
- **Icons (bundle via Nexus npm, never CDN):** Lucide, Tabler, Heroicons, Phosphor, Iconoir. **Illustrations (recolorable SVG):** unDraw, Open Peeps, Humaaans — ship as SVG so the studio color picker recolors them (`remotion-svg-colors`).
|
||||
- **Icons (bundle via Nexus npm, never CDN):** Lucide, Tabler, Heroicons, Phosphor, Iconoir. **Illustrations (recolorable SVG):** unDraw, Open Peeps, Humaaans — ship as SVG so the studio color picker recolors them (`../remotion-svg-colors/SKILL.md`).
|
||||
|
||||
**Iran access:** generally reachable — Pixabay, Mixkit, Coverr, Poly Haven, ambientCG, npm via Nexus. VPN-recommended/intermittent — Pexels, Unsplash, Sketchfab, GitHub raw. Sanction-blocked at account/payment — Adobe Stock, Envato. **Mitigation: batch all sourcing in one "asset run" over a stable tunnel, commit binaries, render never touches the open internet again.**
|
||||
|
||||
@@ -218,8 +218,8 @@ Ordered by ROI. Each item ties to our stack and the relevant skill file.
|
||||
**Tier 1 — highest-ROI template work**
|
||||
4. **Build a "captions" engine as a reusable first-class layer** — word-by-word kinetic captions, high-contrast white/yellow + black outline, lower-middle-third, safe-zoned for all platforms, beat-syncable. This is currently an afterthought and is the biggest cross-platform win. *(Masterpiece §4, Animation §2.)*
|
||||
5. **Ship the "kinetic oversized type + grain" template** — every aspect, cheap (CSS), uses variable Vazirmatn weight-animation for Persian hero type. Highest ROI per the trends brief. *(Trends §1, Animation §2.)*
|
||||
6. **Codify the pre-ship polish checklist + 8 layers into a review gate** (extend `flatrender-template-seo`'s publish step, or a new lint pass) so no template ships without easing, beat-synced audio, three-aspect verification, and a hero moment. *(Masterpiece §4.)*
|
||||
7. **Sound-design pass on the existing pack** — wire `remotion-music-picker` BPM mapping + `remotion-sound-effects` placement + ducking into our current templates. Fastest "professional" upgrade to what already exists. *(Masterpiece §4.)*
|
||||
6. **Codify the pre-ship polish checklist + 8 layers into a review gate** (extend `../flatrender-template-seo/SKILL.md`'s publish step, or a new lint pass) so no template ships without easing, beat-synced audio, three-aspect verification, and a hero moment. *(Masterpiece §4.)*
|
||||
7. **Sound-design pass on the existing pack** — wire `../remotion-music-picker/SKILL.md` BPM mapping + `../remotion-sound-effects/SKILL.md` placement + ducking into our current templates. Fastest "professional" upgrade to what already exists. *(Masterpiece §4.)*
|
||||
|
||||
**Tier 2 — premium differentiation**
|
||||
8. **3D logo-reveal template + a liquid-chrome variant** on `@remotion/three` + HDRI (`three-kit.tsx` `StudioEnv/Lights/Floor/Effects`), all motion off `useCurrentFrame()`. Premium tier. *(Trends §1, Animation §2.)*
|
||||
@@ -228,7 +228,7 @@ Ordered by ROI. Each item ties to our stack and the relevant skill file.
|
||||
|
||||
**Tier 3 — craft & process maturity**
|
||||
11. **Adopt the 5-pass workflow (reference → blocking → timing → polish → review) as the team norm**, and seed a reference library (AE templates / Dribbble loops) per template type. *(Animation §2.)*
|
||||
12. **Per-aspect tuning audit** of existing templates — stagger + scale via `pick`, re-flow not letterbox, confirm Persian RTL never clips. *(Animation §2, `remotion-aspect-ratios`.)*
|
||||
12. **Per-aspect tuning audit** of existing templates — stagger + scale via `pick`, re-flow not letterbox, confirm Persian RTL never clips. *(Animation §2, `../remotion-aspect-ratios/SKILL.md`.)*
|
||||
13. **Color system discipline** — enforce dopamine-accent-+-neutral/pastel-base + grain-overlay defaults; run user hex through the grade so no garish value breaks a look. *(Trends §1, Masterpiece §4.)*
|
||||
|
||||
---
|
||||
@@ -88,4 +88,4 @@ Reject if: text is clipped at any edge, an element is off-frame, the hero is tin
|
||||
- [ ] Spread/count adjusted for narrow frames; 3D fov/camera tuned per aspect.
|
||||
- [ ] Eyeballed stills in ALL THREE aspects.
|
||||
|
||||
Related: `remotion-template-composition`, `remotion-design-styles`.
|
||||
Related: `../remotion-template-composition/SKILL.md`, `../remotion-design-styles/SKILL.md`.
|
||||
@@ -46,6 +46,6 @@ Build the figure from: `sphereGeometry` (head/joints), `cylinderGeometry`/`capsu
|
||||
- If a GLTF model IS provided, load with drei `useGLTF` and animate transforms by `frame` (no `useFrame`).
|
||||
|
||||
## Workflow
|
||||
Storyboard → build parts → rig groups → animate cycles → **render stills at 3-4 beats and LOOK** → refine → render all 3 aspects (see `remotion-aspect-ratios` — characters must sit in the safe zone in 9:16 too).
|
||||
Storyboard → build parts → rig groups → animate cycles → **render stills at 3-4 beats and LOOK** → refine → render all 3 aspects (see `../remotion-aspect-ratios/SKILL.md` — characters must sit in the safe zone in 9:16 too).
|
||||
|
||||
Related: `remotion-design-styles`, `remotion-aspect-ratios`, `remotion-template-catalog`.
|
||||
Related: `../remotion-design-styles/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../remotion-template-catalog/SKILL.md`.
|
||||
@@ -26,7 +26,7 @@ Each template should commit to ONE art style — mixing reads as "basic". Catalo
|
||||
- **3D (@remotion/three):** depth, real lighting/reflections, bokeh, camera moves. Use for premium logo/product/abstract reveals. Costs render time. Setup is already done: R3F v9 + `Config.setChromiumOpenGlRenderer("angle")`. Reuse `three-kit.tsx` (StudioEnv, StudioLights, StudioFloor, StudioEffects, Confetti3D). Keep crisp Persian text as a 2D `<AbsoluteFill>` overlay ON TOP of `<ThreeCanvas>` — don't render Persian text in 3D.
|
||||
|
||||
## Color design
|
||||
- Drive every colorable element from the `colorSchema` props (accent / secondary / background / text) so the studio can recolor it — see `remotion-svg-colors`.
|
||||
- Drive every colorable element from the `colorSchema` props (accent / secondary / background / text) so the studio can recolor it — see `../remotion-svg-colors/SKILL.md`.
|
||||
- Build depth with VALUE, not just hue: dark bg → mid elements → bright accents/highlights. Add glow (`hexToRgba(accent, .6)` shadows) and a vignette (`inset 0 0 600px rgba(0,0,0,.6)`).
|
||||
- Gradients: 2-3 stops max; blend related hues (`mixHex(a,b,.5)`). Mesh look = several large blurred radial-gradient circles drifting on `sin(frame/…)`.
|
||||
- Contrast: text needs ≥ 4.5:1 over its backdrop — add a scrim/shadow when over busy/3D scenes.
|
||||
@@ -46,4 +46,4 @@ Stagger entrances (don't reveal everything at once), use `spring()` for pops and
|
||||
- Renders deterministically (no random/date).
|
||||
- Verify visually: render stills at 3-4 key frames and LOOK before shipping.
|
||||
|
||||
Related: `remotion-character-design`, `remotion-aspect-ratios`, `remotion-template-composition`, `remotion-svg-colors`.
|
||||
Related: `../remotion-character-design/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../remotion-template-composition/SKILL.md`, `../remotion-svg-colors/SKILL.md`.
|
||||
@@ -56,4 +56,4 @@ const f = useCurrentFrame();
|
||||
3. Re-time the key reveals to the chosen BPM's beats.
|
||||
4. Add `<Audio>` with fades; render and LISTEN; nudge beats until reveals hit on the downbeat.
|
||||
|
||||
Related: `remotion-sound-effects`, `remotion-template-catalog`.
|
||||
Related: `../remotion-sound-effects/SKILL.md`, `../remotion-template-catalog/SKILL.md`.
|
||||
@@ -19,7 +19,7 @@ import { Audio, useVideoConfig } from "remotion";
|
||||
Patterns:
|
||||
- Wrap one-shots in `<Sequence from={FRAME}>` so they trigger at the right beat.
|
||||
- `volume` can be a function of frame for fades: `volume={(f)=>interpolate(f,[0,10],[0,1])}`.
|
||||
- Layer SFX over the music bed (see `remotion-music-picker`); keep SFX ~ -6 dB under dialogue, on top of music.
|
||||
- Layer SFX over the music bed (see `../remotion-music-picker/SKILL.md`); keep SFX ~ -6 dB under dialogue, on top of music.
|
||||
- Put shared SFX in `services/remotion/public/sfx/` and load with `staticFile()`.
|
||||
|
||||
## SFX → moment mapping (sync to the KEYFRAME, not vaguely)
|
||||
@@ -53,4 +53,4 @@ Mixkit, Pixabay (sound), Freesound (check each license — CC0 vs attribution),
|
||||
3. Place via `<Sequence from={frame}>` + `<Audio>`; tune volume + a short fade.
|
||||
4. Render with audio and LISTEN — adjust timing by a few frames so hits land exactly on the visual.
|
||||
|
||||
Related: `remotion-music-picker`, `remotion-template-composition`.
|
||||
Related: `../remotion-music-picker/SKILL.md`, `../remotion-template-composition/SKILL.md`.
|
||||
@@ -42,4 +42,4 @@ A full Remotion/AE re-render is too slow for a color picker. So a scene is also
|
||||
- Key mismatch (SVG `data-color-key` ≠ schema prop ≠ seeded `element_key`) breaks the binding — keep ONE naming source of truth.
|
||||
- Contrast: when users can recolor text + background, enforce/encourage a min contrast or the text can vanish.
|
||||
|
||||
Related: `remotion-template-composition`, `remotion-design-styles`.
|
||||
Related: `../remotion-template-composition/SKILL.md`, `../remotion-design-styles/SKILL.md`.
|
||||
@@ -44,11 +44,11 @@ Use this map to pick the NEXT one and to scope a request into a pattern. Each ro
|
||||
|
||||
## How to choose next
|
||||
1. Prefer **gaps** with high value for an Iran-facing product: Yalda, wedding, product showcase, testimonial, lower-thirds, outro/subscribe, music visualizer.
|
||||
2. Pick a STYLE that differs from neighbors (don't ship five dark-particle reveals) — see `remotion-design-styles`.
|
||||
2. Pick a STYLE that differs from neighbors (don't ship five dark-particle reveals) — see `../remotion-design-styles/SKILL.md`.
|
||||
3. Decide 2D vs 3D by subject (logos/products/abstract → 3D shines; text/character/illustrative → 2D or hybrid).
|
||||
4. Confirm a storyboard with the user for anything character- or scene-heavy.
|
||||
|
||||
## Per-template build steps
|
||||
Storyboard (confirm) → build composition (lib helpers, design-styles, character-design) → make it fit all aspects (`remotion-aspect-ratios`) → wire editable text/logo/colors (`remotion-template-composition`, `remotion-svg-colors`) → pick fonts (`persian-fonts`) → optional music/SFX → render thumbnails + preview → seed (`scripts/seed_remotion_templates.py`) → deploy.
|
||||
Storyboard (confirm) → build composition (lib helpers, design-styles, character-design) → make it fit all aspects (`../remotion-aspect-ratios/SKILL.md`) → wire editable text/logo/colors (`../remotion-template-composition/SKILL.md`, `../remotion-svg-colors/SKILL.md`) → pick fonts (`../persian-fonts/SKILL.md`) → optional music/SFX → render thumbnails + preview → seed (`scripts/seed_remotion_templates.py`) → deploy.
|
||||
|
||||
Related: every other remotion-* skill.
|
||||
+4
-4
@@ -8,7 +8,7 @@ description: How to compose the editable elements of a FlatRender template — t
|
||||
A template is not just a nice animation — it's a *fill-in-the-blanks* product. Users edit a few fields and it must look great with THEIR text/logo. Design for editability + clarity.
|
||||
|
||||
## The binding model (how editable fields work)
|
||||
Editable elements live in the DB and bind to Remotion props by KEY (see `remotion-svg-colors` for the full pipeline):
|
||||
Editable elements live in the DB and bind to Remotion props by KEY (see `../remotion-svg-colors/SKILL.md` for the full pipeline):
|
||||
- **Text** → `content.scene_content_elements` of type `Text`; the element `key` MUST equal the composition's Zod schema field (e.g. `headline`, `tagline`). Studio shows a text input.
|
||||
- **Logo / image / media** → a `scene_content_elements` of type `Media`; key = a `z.string()` prop (e.g. `logoUrl`). Studio shows upload/replace. In the composition: `logoUrl ? <Img src={logoUrl}> : <DefaultMark/>`. See `GlitterReveal.tsx`.
|
||||
- **Colors** → `shared_colors` / `scene_color_elements`, key = a `colorSchema` prop.
|
||||
@@ -26,8 +26,8 @@ Size ratios that read well: primary `vmin(80-110)`, secondary `vmin(26-40)`, ter
|
||||
|
||||
## Text legibility (critical over busy/3D backgrounds)
|
||||
- Add a scrim or shadow: `textShadow: 0 0 vmin(20) rgba(0,0,0,.7)`, or a semi-transparent panel behind text.
|
||||
- Persian is RTL: set `direction: "rtl"`, use `FONT` (Vazirmatn) from `lib/fonts.ts`. See `persian-fonts`.
|
||||
- Keep line length comfortable (`maxWidth ~ 86%`); never let text touch frame edges (see `remotion-aspect-ratios`).
|
||||
- Persian is RTL: set `direction: "rtl"`, use `FONT` (Vazirmatn) from `lib/fonts.ts`. See `../persian-fonts/SKILL.md`.
|
||||
- Keep line length comfortable (`maxWidth ~ 86%`); never let text touch frame edges (see `../remotion-aspect-ratios/SKILL.md`).
|
||||
- For gradient text use `backgroundClip: text` + a `drop-shadow` for separation.
|
||||
|
||||
## Logo placement
|
||||
@@ -57,4 +57,4 @@ Give each text element ~0.6-0.8s on screen minimum before the next competes.
|
||||
- [ ] Staggered, eased reveal with a final hold.
|
||||
- [ ] Looks good with long Persian text and a tall logo (test it).
|
||||
|
||||
Related: `remotion-svg-colors`, `remotion-aspect-ratios`, `persian-fonts`, `remotion-design-styles`.
|
||||
Related: `../remotion-svg-colors/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../persian-fonts/SKILL.md`, `../remotion-design-styles/SKILL.md`.
|
||||
@@ -88,7 +88,7 @@ For a full template: write a **beat list first** (logo in → tagline → 3 feat
|
||||
- **Window:** scene transition **12–20f**; whip/cut feels best at the short end, dissolve/camera at the long end.
|
||||
- **Entrances ease-out** (`Easing.out(Easing.quint)` / `Easing.bezier(0.16,1,0.3,1)`); **exits ease-in and always SHARPER than the entrance** — scenes leave faster than they arrive.
|
||||
- **A→B on-screen / camera = ease-in-out.** **Linear ONLY** for continuous rotation/marquee.
|
||||
- Snap transition `from` frames to the **music beats** (`remotion-music-picker`) so cuts land on downbeats.
|
||||
- Snap transition `from` frames to the **music beats** (`../remotion-music-picker/SKILL.md`) so cuts land on downbeats.
|
||||
- Per-aspect: tighten the window on `isWide` (reads faster), loosen on `isTall`. Use the proposed `pick(wide,square,tall)` helper on `Layout` when it lands; until then branch on `isWide/isSquare/isTall`.
|
||||
|
||||
## Reusable transition components
|
||||
@@ -106,7 +106,7 @@ export const Dissolve: React.FC<{ children: React.ReactNode; win: number }> = ({
|
||||
return <AbsoluteFill style={{ opacity: o }}>{children}</AbsoluteFill>;
|
||||
};
|
||||
```
|
||||
Make sibling wrappers `Wipe`, `CircleReveal`, `WhipZoom`, `ShapeWipe` with the same `(children, win, dir)` contract so a template can swap transitions by changing one wrapper. Keep the SFX hook in mind: a whoosh 2–3f before the cut + an impact ON it (`remotion-sound-effects`).
|
||||
Make sibling wrappers `Wipe`, `CircleReveal`, `WhipZoom`, `ShapeWipe` with the same `(children, win, dir)` contract so a template can swap transitions by changing one wrapper. Keep the SFX hook in mind: a whoosh 2–3f before the cut + an impact ON it (`../remotion-sound-effects/SKILL.md`).
|
||||
|
||||
## Pre-ship transition checklist
|
||||
- [ ] No back-to-back `<Sequence>`s where a join should be smooth — scenes **overlap** the window.
|
||||
@@ -118,4 +118,4 @@ Make sibling wrappers `Wipe`, `CircleReveal`, `WhipZoom`, `ShapeWipe` with the s
|
||||
- [ ] Verified in 16:9 / 1:1 / 9:16 — wipe direction & blur amount read the same (`vmin`, not px); Persian RTL wipes from the right.
|
||||
- [ ] Colors via `colorSchema` (`mixHex`/`hexToRgba`), never hardcoded; deterministic (re-render twice → identical).
|
||||
|
||||
Related: `remotion-template-composition`, `remotion-aspect-ratios`, `remotion-design-styles`, `remotion-sound-effects`, `remotion-music-picker`, `remotion-character-design`, `remotion-svg-colors`, `persian-fonts`, `flatrender-template-seo`.
|
||||
Related: `../remotion-template-composition/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../remotion-design-styles/SKILL.md`, `../remotion-sound-effects/SKILL.md`, `../remotion-music-picker/SKILL.md`, `../remotion-character-design/SKILL.md`, `../remotion-svg-colors/SKILL.md`, `../persian-fonts/SKILL.md`, `../flatrender-template-seo/SKILL.md`.
|
||||
@@ -5,7 +5,7 @@ description: How to design the scroll-stopping first 1-3 seconds of a FlatRender
|
||||
|
||||
# The hook (first 1-3 seconds — where templates are won or lost)
|
||||
|
||||
On a 9:16 feed the viewer decides **stay or swipe in 2-3 seconds** (TikTok's "3-second rule"; IG rewards 3-sec view rate). YouTube Shorts has **no runway** — open on the most compelling moment. So a FlatRender template doesn't get a polite logo intro: the **first frame is the cover/thumbnail and the hook**, and the first ~45-90 frames (@30fps) must arrest the eye. Everything here is a *pure function of `useCurrentFrame()`* — no `Math.random`/`Date.now`/`useFrame`; use `rand(seed)` from `lib/anim.ts`. Read `remotion-aspect-ratios` before positioning a single hook element.
|
||||
On a 9:16 feed the viewer decides **stay or swipe in 2-3 seconds** (TikTok's "3-second rule"; IG rewards 3-sec view rate). YouTube Shorts has **no runway** — open on the most compelling moment. So a FlatRender template doesn't get a polite logo intro: the **first frame is the cover/thumbnail and the hook**, and the first ~45-90 frames (@30fps) must arrest the eye. Everything here is a *pure function of `useCurrentFrame()`* — no `Math.random`/`Date.now`/`useFrame`; use `rand(seed)` from `lib/anim.ts`. Read `../remotion-aspect-ratios/SKILL.md` before positioning a single hook element.
|
||||
|
||||
## The frame budget for the open (30fps; use `sec(s)=Math.round(s*fps)`)
|
||||
| Beat | Frames | Job |
|
||||
@@ -14,7 +14,7 @@ On a 9:16 feed the viewer decides **stay or swipe in 2-3 seconds** (TikTok's "3-
|
||||
| **Pattern interrupt** | 0-12 | One bold motion/sound jolt that breaks the scroll rhythm. |
|
||||
| **Hook text lands** | 6-30 | The promise/question/claim, big, high-contrast, lower-middle third. |
|
||||
| **Curiosity hold** | 30-75 | Pose an open loop the rest of the video closes. Don't resolve yet. |
|
||||
| **Hero handoff** | 60-90 | Flow into logo/headline (`remotion-template-composition`). |
|
||||
| **Hero handoff** | 60-90 | Flow into logo/headline (`../remotion-template-composition/SKILL.md`). |
|
||||
|
||||
Front-load the payoff — **no preamble, no slow brand sting first**. Brand comes *after* the hook earns the watch.
|
||||
|
||||
@@ -34,10 +34,10 @@ Use Persian numerals (`۰-۹`) — never Latin digits — in hook copy and count
|
||||
## Pattern interrupts (the scroll-breaking jolt in f0-12)
|
||||
The feed has a rhythm; a hook *breaks* it. Stack 1-2 of these, never all:
|
||||
- **Motion jolt** — whip-in with overshoot: `Easing.bezier(0.34,1.56,0.64,1)`, or a low-damping `spring({mass:0.6,damping:9,stiffness:200})`. Add motion blur on the fast frames (its absence is an amateur tell).
|
||||
- **Hard cut + flash** — a 1-2 frame white/accent wash: `opacity = frame < 2 ? 1 : 0` over a `hexToRgba(accentColor, …)` fill. Pair with a thump SFX (`remotion-sound-effects`).
|
||||
- **Hard cut + flash** — a 1-2 frame white/accent wash: `opacity = frame < 2 ? 1 : 0` over a `hexToRgba(accentColor, …)` fill. Pair with a thump SFX (`../remotion-sound-effects/SKILL.md`).
|
||||
- **Scale punch** — start at `scale` 1.6→1.0 (clamp) so the subject "slams" toward camera.
|
||||
- **Color shock** — open on a dopamine accent (electric blue/coral/acid) on a neutral base; pull it from `accentColor` so the studio recolors it.
|
||||
- **Silence-then-hit** — a held silent f0-8, then riser+downbeat on the hook (`remotion-music-picker` BPM map). The pause *is* the interrupt.
|
||||
- **Silence-then-hit** — a held silent f0-8, then riser+downbeat on the hook (`../remotion-music-picker/SKILL.md` BPM map). The pause *is* the interrupt.
|
||||
|
||||
```tsx
|
||||
// Pattern-interrupt whip-in for the hook line (deterministic, clamped)
|
||||
@@ -97,8 +97,8 @@ return (
|
||||
| **All three** | 1-2s | first frame = hook = cover; authenticity > gloss | hook prop in every aspect, re-flowed not letterboxed |
|
||||
|
||||
## Tie the hook into template structure
|
||||
- Make the hook copy a Zod prop (e.g. `hookText: z.string()`) + a seeded `Text` element whose `key` matches — same binding model as `remotion-template-composition`. Ship strong Persian default copy so it reads finished pre-edit.
|
||||
- Hook color = `accentColor`/`textColor` from `colorSchema`; pass user hex through a grade so a garish value doesn't break the open (`remotion-svg-colors`).
|
||||
- Make the hook copy a Zod prop (e.g. `hookText: z.string()`) + a seeded `Text` element whose `key` matches — same binding model as `../remotion-template-composition/SKILL.md`. Ship strong Persian default copy so it reads finished pre-edit.
|
||||
- Hook color = `accentColor`/`textColor` from `colorSchema`; pass user hex through a grade so a garish value doesn't break the open (`../remotion-svg-colors/SKILL.md`).
|
||||
- The hook is a `<Sequence from={0} durationInFrames={sec(2.5)}>`; the hero sequence overlaps its tail so the handoff is a flow, not a cut.
|
||||
- 3D hooks: keep the interrupt object filling the frame per aspect (tune `fov`/`position.z`), drive entrance from `useCurrentFrame()` with high `mass` for weight; let `StudioEffects` (bloom/DOF/vignette) finish it.
|
||||
|
||||
@@ -111,4 +111,4 @@ return (
|
||||
- [ ] Eased/overshoot motion (no linear), held for the read, with a tiny live shimmer; animated grain from f0.
|
||||
- [ ] Verified the open in all three aspects (`pick`-tuned), recolors cleanly, re-renders identical (deterministic).
|
||||
|
||||
Related: `remotion-template-composition`, `remotion-aspect-ratios`, `remotion-design-styles`, `remotion-sound-effects`, `remotion-music-picker`, `remotion-svg-colors`, `persian-fonts`, `remotion-template-catalog`, `flatrender-template-seo`.
|
||||
Related: `../remotion-template-composition/SKILL.md`, `../remotion-aspect-ratios/SKILL.md`, `../remotion-design-styles/SKILL.md`, `../remotion-sound-effects/SKILL.md`, `../remotion-music-picker/SKILL.md`, `../remotion-svg-colors/SKILL.md`, `../persian-fonts/SKILL.md`, `../remotion-template-catalog/SKILL.md`, `../flatrender-template-seo/SKILL.md`.
|
||||
Reference in New Issue
Block a user