Files
flatrender/services/remotion/docs/ASSET_LIBRARY.md
T
soroush.asadi cb6512fee3 feat(remotion): asset-library catalog + Phase 0 (license firewall, @remotion/lottie, 30 CC0 characters)
- docs/ASSET_LIBRARY.md: curated catalog from the asset sweep (91 sources -> 62
  usable) + completeness-critic reality check; clean CC0/MIT tier, license/geo
  traps, and the 2.5D layered-scene plan (sky->room->furniture->device->character
  ->grain) to fix the "naked scene".
- deps: add @remotion/lottie@4.0.290 (runtime) + DiceBear (build-time devDep).
- scripts/gen-dicebear.mjs: generate 30 CC0 Open-Peeps characters OFFLINE (no
  runtime CDN) into public/illustrations/dicebear/ + a per-file assets.json ledger.
- scripts/check-assets.mjs: license-firewall CI guard — fails on any un-ledgered
  vendored asset.
- AssetSheet dev composition: proves vendored SVG -> staticFile() -> Remotion render
  (30 real characters render cleanly).
- NOTE: GitHub (Open Peeps/IRA/Notion git clones) + Gumroad (Lukasz) are geo-blocked
  headless here; those + Humaaans (Figma export) need a manual/mirror fetch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 18:59:03 +03:30

22 KiB
Raw Blame History

FlatRender — Curated Asset Library Catalog

Generated by the flatrender-asset-sweep workflow (91 sources surveyed → 62 usable after adversarial license/Iran-access verification) + a completeness-critic pass. Read §12 (Reality Check) before treating any count as "done". Nothing here is vendored yet — this is an acquisition + build plan, not a shipped library.

Reference look: Google "Alegria" / Pablo-Stanley flat editorial illustration — bold flat colour-blocking (23 shades per shape), confident hand-drawn line, expressive hands & foreshortening, characters set in rich scenes (rooms, furniture, devices, sky), subtle grain.

Render stack (verified in repo): Remotion 4.0.290 + @remotion/three 4.0.290 (installed). @remotion/lottie is NOT yet a dependency in services/remotion/package.json — it must be added (MIT, Nexus-mirrorable) before any Lottie path works.

Stack rule (standing): every template animation is built on Remotion + Three.js together (@remotion/three). Flat-illustration art is composited as 2.5D — 2D layers placed on planes inside a Three.js scene for parallax camera, depth, lighting and 3D particles. Animate only off useCurrentFrame().

Vendoring target (verified): services/remotion/public/ exists and currently holds only fonts/ (Vazirmatn 400900 woff2). The project already serves vendored files via staticFile() (see src/lib/fonts.ts and AppShowcase3D.tsx). All asset categories below land under public/illustrations/... and public/lottie/....

The "naked scene" problem (verified): src/compositions/CharacterStory.tsx draws a single hand-coded SVG figure standing on an abstract blurred blob inside a gradient — no room, no furniture, no real sky, no props. The catalog and integration plan below exist specifically to fix this with a layered, asset-driven scene system.


0. Totals (claimed — see §12 for the honest correction)

Bucket Claimed usable count
Characters — riggable (separable parts) ~110 base components / poses (Humaaans ~100 + Open Peeps part-set)
Characters — Lottie/animated (self-authored + curated CC0) ~5080 loops (mostly self-authored)
Scenes & interiors (recolorable, vendor curated subset) ~300+ curated (from unDraw/ManyPixels/Lukasz pools of 4,000+)
Devices / props ~150
Sky / nature / abstract ~80
Grain / texture ~10
Persian / seasonal ~40 (self-authored)

⚠️ The critic's verdict: this "≥100 characters" is permutation-inflated. The defensible count of distinct, named, ledgered figures from the firewall-clean CC0/MIT tier is ~5060, and 0 are riggable today (all need manual <g>-splitting). §12 gives a concrete plan to a real, enumerated 100-figure roster.


1. Characters — Riggable (separable SVG parts) core tier

Individual <g> body parts can be driven by useCurrentFrame() / interpolate() — true per-limb rigging, not just whole-figure parallax.

1.1 Humaaans (Pablo Stanley) — FLAGSHIP

  • License: CC0 1.0 Public Domain (commercial OK, no attribution, redistribution/vendoring OK).
  • Iran-access: acquisition yes (humaaans.com / Figma Community / archive.org). Do NOT use Gumroad. Render-time is CDN-free once vendored.
  • Animation-fit: riggable-parts — realistically 78/10. Parts are separable as components in the Figma/Sketch source; a flat one-shot SVG export flattens groups, so you must export each body part as its own <g> first.
  • Count: ~100 base components (≈12 base poses + dozens of heads/hair/tops/bottoms/shoes + objects).
  • Style-match: 9/10 — THE flagship Alegria reference.
  • Download: Figma Community file 1200350623263197299 → export per-part SVGs; or humaaans.com; archive.org/details/humaaans fallback.
  • Use-cases: full-body hero rigging; per-limb wave/present/think/celebrate poses (replaces the hand-coded Pose system in CharacterStory.tsx).

1.2 Open Peeps (Pablo Stanley) — secondary

  • License: CC0 1.0 (no attribution, redistribution OK).
  • Iran-access: acquisition yes. Animation-fit: riggable-parts — github.com/opeepsfun/open-peeps exposes separated body/head/face/beard/accessory SVGs (npm wrapper is MIT; vendor the raw CC0 SVGs, not the wrapper).
  • Count: ~200 building-block parts. Style-match 7/10 (confident hand-drawn line; lighter colour-blocking). Character-only — pair with §3 scenes.
  • ⚠️ Do NOT confuse with Avataaars (same artist, NOT CC0).

1.3 DiceBear (programmatic, offline) — build-time avatars

  • License: core MIT; per-style — open-peeps=CC0, avataaars=free-commercial custom, big-smile/adventurer/croodles=CC BY 4.0 (attribution REQUIRED).
  • Iran-access: yes@dicebear/core + @dicebear/collection run fully offline via npm (Nexus mirror). createAvatar(style,{seed}).toString() → raw SVG, no runtime CDN. Do NOT call the dicebear HTTP API at render.
  • Animation-fit: component-swap + transforms (blink/expression micro-rigs), not full skeletal rig. Bust→half-body scale.
  • Count: ~45 styles. Style-match 6/10. Use idRandomization to avoid SVG id collisions.

1.4 IRA Design (Creative Tim) — selective gradient style

  • License: MIT (ira-design/ira-illustrations). Retain LICENSE.md alongside vendored SVGs (no on-screen credit needed).
  • Iran-access: yes (git clone). Animation-fit: moderate — monolithic per-illustration files, manual <g> split needed; gradient fills complicate flat parallax.
  • Count: ~100 vendorable SVGs (36 characters + 52 objects + backgrounds). Style-match 6/10 (gradient sketch, not strict flat-block).

1.5 Avataaars (Pablo Stanley) — ⚠️ caution

  • License: code ports MIT, but artwork is custom "free for personal & commercial use", NOT MIT/CC0 — no redistribution "in a pack", no "use to create a competing service" (a live risk for an avatar SaaS).
  • Verdict: talking-head micro-animation only (via DiceBear avataaars offline npm); document as "permissive-with-restrictions"; do NOT build a user-facing avatar generator on it.

2. Characters — Lottie / Animated

Strategic note: every third-party Lottie library carries a redistribution and/or competing-service clause that collides with a paid template SaaS vendoring assets into public/. Primary path = SELF-AUTHOR brand Lottie loops from the CC0 SVGs in §1/§3 and drive them with @remotion/lottie.

  • 2.1 LottieFiles (free/community)⚠️ Simple License (commercial OK) but no "compile files to develop a competing service", no standalone JSON redistribution; per-file Free/Premium badge. Iran-access unknown (login-gated). Use only inside a final render, Free badge re-verified.
  • 2.2 Lottielab⚠️ free tier watermarks all exports; value is as an authoring tool on cleanly-licensed SVGs (Pro ~$12/mo for watermark-free).
  • 2.3 LottieFiles creators/marketplace⚠️ per-item; only Free-badged vendorable; Premium forbids redistribution even after purchase. Style-match up to 8/10 for the right creator.

3. Scenes & Interiors (recolorable flat backdrops — fixes the "naked scene")

The category that directly cures CharacterStory.tsx — flat scene SVGs (rooms, desks, cities, devices, sky) used as BACKGROUND/MID-GROUND layers behind the riggable §1 characters; animation is whole-scene parallax/recolor.

  • 3.1 unDraw⚠️ NOT MIT (stale label) → custom proprietary (free commercial, no attribution) that forbids replicating a competing service, distributing "in packs", scraping, AND AI/ML training. ~1,300 scenes. Style-match 23/10. Hand-pick only (no bulk scrape), bake into renders, log license="unDraw custom (proprietary)".
  • 3.2 ManyPixels⚠️ custom permissive but forbids "distribute in packs", being the product's center, AND AI-training. 2,500+. Iran-access yes (Iconduck/quentincaffeino/manypixels-illustrations mirror). Style-match 4/10. Curated subset baked in; never an in-product picker.
  • 3.3 Lukasz Adam⚠️ CC0/MIT (cleanest scene tier) but acquisition NO via official Gumroad (sanctioned) → Eagle/aggregator mirror or non-Iran box. 229 confirmed (characters, remote-work, cities, devices). The free-static scene anchor.
  • 3.4 Storyset (Freepik)⚠️ reference only — resale/database clause + visible Freepik credit; Iran-access NO (OFAC checkout). Only attractive property: exports Lottie JSON.
  • 3.5 DrawKit⚠️ freemium proprietary, forbids standalone redistribution + AI-training, revocable terms. Use only if repo private + users get rendered output only.
  • 3.6 Black Illustrations⚠️ proprietary; forbids serving raw SVG / end-user extraction → bake into MP4 only. ~120 free. Valuable inclusive-character supplement.
  • 3.7 Ouch! by Icons8⚠️ reference only — forbids distributing as "stand-alone files" (conflicts with public/+staticFile()); Iran-access NO.

4. Devices / Props

  • Humaaans objects (CC0) — laptops/phones/plants/chairs/signs, separable mid-ground props.
  • IRA Design objects (MIT) — 52 objects; split manually.
  • Lukasz Adam "Devices" (CC0) — phones/laptops/monitors; pairs with the AppShowcase3D.tsx screenUrl + staticFile() pattern.
  • Self-authored SVG props — drawn inline in the same flat style (the repo already proves this works).

5. Sky / Nature / Abstract

  • Self-authored gradients & shapes (CSS/SVG, already used in CharacterStory.tsx) — cleanest license-free sky/abstract layer; drift off useCurrentFrame().
  • unDraw/ManyPixels nature (curated, recolored).
  • Three.js abstract via @remotion/three (installed) for parallax sky/particles depth.

6. Grain / Texture

  • Inline feTurbulence SVG noise — ALREADY in CharacterStory.tsx (mixBlendMode: overlay, opacity 0.05). Keep as the standard grain.
  • CC0 paper/noise tiles — vendor 510 (ambientCG / cc0textures, CC0).

7. Persian / Seasonal

  • Self-authored Nowruz (haft-sin, sabzeh, goldfish, sonbol), Yalda (pomegranate, watermelon, Hafez), Ramadan (crescent, fanoos) flat SVG motifs — the repo already ships Nowruz3D.tsx / NowruzGreeting.tsx.
  • Recolored CC0 scenes (Humaaans + Lukasz) dressed with seasonal props. Vazirmatn RTL already vendored.

8. DOWNLOAD MANIFEST

All assets land under services/remotion/public/. npm via the Nexus mirror (mirror.soroushasadi.com). For Gumroad/Freepik/Icons8/Cloudflare-gated sources, acquire from a non-Iran box / VPN once, then commit — render-time is CDN-free.

# 0. Folders
mkdir -p services/remotion/public/illustrations/{humaaans,openpeeps,undraw,manypixels,lukaszadam,ira,notion}
mkdir -p services/remotion/public/lottie

# 1. Humaaans (CC0) — FLAGSHIP. Figma community 1200350623263197299 → export each
#    body-part as its own <g> SVG → public/illustrations/humaaans/  (NOT Gumroad)

# 2. Open Peeps (CC0) — pre-separated parts:
git clone https://github.com/opeepsfun/open-peeps   # vendor raw CC0 SVGs, not the wrapper

# 3. DiceBear (offline, no runtime CDN) — generate at BUILD time:
npm i @dicebear/core @dicebear/collection           # via Nexus mirror
#    createAvatar(openPeeps,{seed}).toString() → write SVG to public/

# 4. IRA Design (MIT) — keep LICENSE.md alongside:
git clone https://github.com/ira-design/ira-illustrations

# 5. Lukasz Adam (CC0, 229) — Eagle/aggregator mirror or non-Iran box (Gumroad sanctioned)

# 6. unDraw / ManyPixels — HAND-PICK only (no bulk scrape); curated subset

# 7. Notion Avatars (CC0) — talking-head busts:
git clone https://github.com/notion-avatar/notion-avatar

# 8. Lottie pipeline (must add the package first):
npm i @remotion/lottie                              # via Nexus — currently MISSING

Iran-mirror flags: Gumroad (Lukasz/Open Peeps/Black Illustrations) = sanctioned. Freepik/Storyset + Icons8 = OFAC-blocked. Cloudflare (DrawKit/ManyPixels) = intermittent. All npm = Nexus mirror.


9. INTEGRATION PLAN

9.1 License firewall — public/illustrations/assets.json

Every vendored file gets one ledger row. No row → asset may not ship.

{
  "humaaans/torso-a.svg": { "source": "Humaaans", "license": "CC0-1.0",
    "license_class": "CC0", "commercial_ok": true, "attribution_required": false,
    "ai_training_allowed": true, "url": "humaaans.com", "vendored": "2026-06-22" },
  "ira/scene-desk.svg": { "source": "IRA Design", "license": "MIT",
    "attribution_required": true, "notice_file": "ira/LICENSE.md", "ai_training_allowed": true },
  "undraw/working.svg": { "source": "unDraw", "license": "unDraw custom (proprietary)",
    "commercial_ok": true, "attribution_required": false,
    "ai_training_allowed": false, "redistribute_as_pack": false }
}

Hard rules: (1) only CC0/MIT/PD vendored as raw public/ SVG; (2) custom-restrictive (unDraw/ManyPixels/DrawKit/Black Illustrations) only as a curated subset baked into renders, ai_training_allowed:false (excluded from FlatRender's future AI-video pipeline); (3) Blush/Storyset/Icons8/Avataaars-pack = never vendored, reference only.

9.2 Rigging an SVG kit in Remotion (useCurrentFrame()-driven <g> parts)

The repo already proves the pattern in CharacterStory.tsx (arm(ang,sign) / leg(sign,ang) rotate <g> groups by frame-derived angles). Replace the hand-drawn paths with vendored Humaaans part SVGs, keep the rig math:

const f = useCurrentFrame();
const wave = pose === "wave" ? 130 + Math.sin(f / 4) * 14 : 12;
<g transform={`translate(${shoulderX} ${shoulderY}) rotate(${wave})`}>
  <UpperArm /> {/* vendored SVG <g>, pivot at shoulder */}
  <g transform={`translate(0 ${forearmY}) rotate(${elbow})`}><Forearm /></g>
</g>

Keep conventions: staticFile() for raster, stable rand(seed) (not Math.random), per-instance id() prefixes (cs${idn}_) to avoid <defs> id collisions, L.vmin()/L.pick() for aspect re-flow.

9.3 @remotion/lottie (after npm i @remotion/lottie)

Vendor JSON under public/lottie/; never a CDN/HTTP API at render. Use for self-authored idle/confetti/sky loops; firewall third-party Premium JSON out.

9.4 LAYER scenes for depth — the cure for "naked scene" (do this in the Three.js 2.5D scene)

Stack layers back-to-front, each on its own plane / parallax speed off useCurrentFrame():

Layer 0  SKY        gradient / Three.js abstract        (slow drift, far plane)
Layer 1  ROOM       vendored interior SVG (wall, window) (slow)
Layer 2  FURNITURE  desk / shelf / plant props          (medium)
Layer 3  DEVICE     laptop/phone (staticFile, AppShowcase pattern)
Layer 4  CHARACTER  riggable Humaaans <g> rig            (foreground, full motion)
Layer 5  GRAIN      feTurbulence overlay (already in repo, opacity 0.05) + vignette

Parallax = depth factor (0.1 … 1.0) on each layer's translate / z-position. Direct upgrade of CharacterStory.tsx: "blob + particles + character" → "sky → room → furniture → device → character → grain".

9.5 Recolor to brand palette

Map colorSchema (accentColor/secondaryColor/backgroundColor/textColor) onto each scene SVG's fills. unDraw exposes one accent var; multi-shade SVGs (Lukasz/ManyPixels/Humaaans) need a small fill-remap at vendor time (mixHex() from src/lib/anim.ts).


10. PHASED BUILD PLAN (to Alegria quality)

  • Phase 0 — Plumbing (½ day). public/illustrations/* + public/lottie/; assets.json ledger + a CI check that fails on un-ledgered files; npm i @remotion/lottie.
  • Phase 1 — Flagship character rig (23 days). Vendor Humaaans parts; build <RiggedCharacter> (separable <g> arms/legs/head, pose presets) reusing the CharacterStory.tsx pose math.
  • Phase 2 — Layered scene system (23 days). <SceneStage> composing sky→room→furniture→device→grain with parallax inside the Three.js scene. Vendor a curated ~30-scene set (Lukasz CC0 first, then hand-picked unDraw/ManyPixels). Rebuild CharacterStory.tsx's 13 beats with real environments.
  • Phase 3 — Recolor + brand binding (12 days). Wire colorSchema → scene fills; verify studio colour controls recolor the whole stack.
  • Phase 4 — Lottie & motion polish (2 days). Self-author 810 idle/wave/confetti/sky loops; integrate via @remotion/lottie; per-limb secondary motion + foreshortening on the hero (expressive hands).
  • Phase 5 — Persian/seasonal pack (12 days). Nowruz/Yalda/Ramadan prop sets on the layered scenes (reuse Nowruz3D).
  • Phase 6 — QA & firewall audit (1 day). Render 3 aspects; confirm determinism, no runtime CDN, full assets.json coverage, AI-prohibited assets flagged out.

11. Verdict summary

Source Verdict Vendor raw? License Iran (acquire) Anim-fit Style
Humaaans USE CC0 yes rig 78 9
Open Peeps USE CC0 yes rig 7
DiceBear (CC0/free) USE gen→commit MIT+CC0 yes (offline npm) swap/transform 6
IRA Design USE (selective) +LICENSE.md MIT yes moderate 6
Lukasz Adam USE (mirror) CC0 acquire NO (Gumroad) single-svg 4
Notion Avatars USE (add) CC0 yes bust micro-rig 6
unDraw caution curated/baked custom-restrictive unknown single-svg 23
ManyPixels caution curated/baked custom-permissive yes single-svg 4
Black Illustrations caution bake-into-MP4 proprietary unknown single-svg 4
Avataaars (art) caution gen→commit, no pack custom-permissive yes bust micro-rig 6
LottieFiles (free) caution inside-render only Simple License unknown lottie 56
DrawKit caution private repo only freemium-proprietary unknown lottie 4
Storyset reference only resale-ban NO lottie 5
Ouch!/Icons8 reference only no stand-alone files NO lottie 5
Blush reference only proprietary NO (Stripe) rig (paid) 9

Bottom line: Build the production library on the clean, vendorable CC0/MIT tier — Humaaans, Open Peeps, DiceBear-CC0, IRA, Notion Avatars + Lukasz Adam scenes; supplement scenery with curated, baked-in unDraw/ManyPixels; self-author Lottie loops; keep the encumbered/Iran-blocked sources (Blush/Storyset/Icons8/DrawKit) as design-time reference only.


12. ⚠️ Reality Check (completeness critic) — READ THIS

The "≥100 characters" in §0 does not survive scrutiny. Honest status and the fix:

Gaps:

  1. Count is permutation-inflated. "Humaaans ~100 components" = interchangeable heads/hair/tops/bottoms, not 100 figures. Defensible distinct, named, firewall-clean figures ≈ 12 Humaaans poses + 36 IRA + a few DiceBear seeds ≈ 5060 — and those need manual <g>-splitting before riggable.
  2. Nothing is vendored yet. public/ contains only fonts/. public/illustrations/ + public/lottie/ don't exist. The catalog is an acquisition plan, not a library. Riggable-today count = 0.
  3. Riggability overstated. A one-shot Humaaans SVG export flattens groups → until per-part <g> export + pivot authoring is done, it's single-figure parallax (same tier as unDraw).
  4. Diversity thin & encumbered. The only dedicated inclusive source (Black Illustrations) is bake-into-MP4-only. No source covers older adults, disability, hijab/chador, or Persian dress beyond self-authored props.
  5. @remotion/lottie is a hard blocker (absent from package.json) — every Lottie path (§2) is non-functional until added; don't count those ~5080 loops yet.
  6. Self-authored assets counted as if they exist (Lottie ~5080, seasonal ~40, sky ~80, props ~150 are future work).

Additions / the concrete fix — enumerate a real 100-figure roster (each an actual committed file + assets.json row):

  • ~30 Humaaans base poses × authored top/bottom/skin variants you actually create & ledger.
  • 36 IRA Design character SVGs (MIT, github.com/ira-design/ira-illustrations).
  • 30 DiceBear open-peeps (CC0) fixed seeds, generated + committed.
  • ~10 Open Peeps part assemblies. → ~106 real, named, ledgered figures.
  • + Notion Avatars (CC0, github.com/notion-avatar/notion-avatar) — ~1015 talking-head busts, firewall-clean, Iran-accessible. Fills the talking-head gap without Avataaars' restrictions.
  • + Croodles / Adventurer (DiceBear, CC BY 4.0 — attribution ledger row) — ~20 doodle-line seeds.
  • + OpenMoji people/gestures (CC BY-SA 4.0, github.com/hfg-gmuend/openmoji) — expressive hands/heads for secondary characters; curated subset + share-alike tracking.
  • Diversity pass: author hijab/scarf head <g> overlays, older-adult variants, varied skin tones via mixHex() recolor on the CC0 Humaaans base (firewall-clean derivative; directly serves the Persian-first product).
  • Grain: vendor 35 CC0 paper/noise tiles from ambientCG (CC0, GitHub/CDN-mirrorable).
  • @remotion/lottie added in Phase 0 before any Lottie asset counts as usable.
  • Sky: add Lukasz Adam CC0 nature SVGs + 23 self-authored gradient-sky presets bound to colorSchema.

So the true near-term deliverable is not "100 characters downloaded" but: Phase 0 plumbing + a vendored, ledgered ~3040 character starter set (Humaaans + IRA + DiceBear + Notion) split into riggable <g> parts, plus a <SceneStage> layered-scene system — enough to rebuild CharacterStory to the Alegria bar — then grow the roster to 100+ on that proven pipeline.