From cb6512fee31cf2ef3166778993b03f54000b5dcd Mon Sep 17 00:00:00 2001 From: "soroush.asadi" Date: Mon, 22 Jun 2026 18:59:03 +0330 Subject: [PATCH] feat(remotion): asset-library catalog + Phase 0 (license firewall, @remotion/lottie, 30 CC0 characters) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- services/remotion/docs/ASSET_LIBRARY.md | 271 ++++++++++ services/remotion/package-lock.json | 486 ++++++++++++++++++ services/remotion/package.json | 7 +- .../remotion/public/illustrations/assets.json | 362 +++++++++++++ .../illustrations/dicebear/openpeeps-01.svg | 1 + .../illustrations/dicebear/openpeeps-02.svg | 1 + .../illustrations/dicebear/openpeeps-03.svg | 1 + .../illustrations/dicebear/openpeeps-04.svg | 1 + .../illustrations/dicebear/openpeeps-05.svg | 1 + .../illustrations/dicebear/openpeeps-06.svg | 1 + .../illustrations/dicebear/openpeeps-07.svg | 1 + .../illustrations/dicebear/openpeeps-08.svg | 1 + .../illustrations/dicebear/openpeeps-09.svg | 1 + .../illustrations/dicebear/openpeeps-10.svg | 1 + .../illustrations/dicebear/openpeeps-11.svg | 1 + .../illustrations/dicebear/openpeeps-12.svg | 1 + .../illustrations/dicebear/openpeeps-13.svg | 1 + .../illustrations/dicebear/openpeeps-14.svg | 1 + .../illustrations/dicebear/openpeeps-15.svg | 1 + .../illustrations/dicebear/openpeeps-16.svg | 1 + .../illustrations/dicebear/openpeeps-17.svg | 1 + .../illustrations/dicebear/openpeeps-18.svg | 1 + .../illustrations/dicebear/openpeeps-19.svg | 1 + .../illustrations/dicebear/openpeeps-20.svg | 1 + .../illustrations/dicebear/openpeeps-21.svg | 1 + .../illustrations/dicebear/openpeeps-22.svg | 1 + .../illustrations/dicebear/openpeeps-23.svg | 1 + .../illustrations/dicebear/openpeeps-24.svg | 1 + .../illustrations/dicebear/openpeeps-25.svg | 1 + .../illustrations/dicebear/openpeeps-26.svg | 1 + .../illustrations/dicebear/openpeeps-27.svg | 1 + .../illustrations/dicebear/openpeeps-28.svg | 1 + .../illustrations/dicebear/openpeeps-29.svg | 1 + .../illustrations/dicebear/openpeeps-30.svg | 1 + services/remotion/scripts/check-assets.mjs | 41 ++ services/remotion/scripts/gen-dicebear.mjs | 53 ++ services/remotion/src/Root.tsx | 11 + .../remotion/src/compositions/AssetSheet.tsx | 38 ++ 38 files changed, 1298 insertions(+), 1 deletion(-) create mode 100644 services/remotion/docs/ASSET_LIBRARY.md create mode 100644 services/remotion/public/illustrations/assets.json create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-01.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-02.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-03.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-04.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-05.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-06.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-07.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-08.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-09.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-10.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-11.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-12.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-13.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-14.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-15.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-16.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-17.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-18.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-19.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-20.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-21.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-22.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-23.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-24.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-25.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-26.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-27.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-28.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-29.svg create mode 100644 services/remotion/public/illustrations/dicebear/openpeeps-30.svg create mode 100644 services/remotion/scripts/check-assets.mjs create mode 100644 services/remotion/scripts/gen-dicebear.mjs create mode 100644 services/remotion/src/compositions/AssetSheet.tsx diff --git a/services/remotion/docs/ASSET_LIBRARY.md b/services/remotion/docs/ASSET_LIBRARY.md new file mode 100644 index 0000000..34e9963 --- /dev/null +++ b/services/remotion/docs/ASSET_LIBRARY.md @@ -0,0 +1,271 @@ +# 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 (2–3 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 400–900 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) | ~50–80 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 **~50–60**, +> and **0 are riggable today** (all need manual ``-splitting). §12 gives a concrete plan to a +> real, enumerated 100-figure roster. + +--- + +## 1. Characters — Riggable (separable SVG parts) ⭐ core tier + +Individual `` 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 7–8/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 `` 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 `` 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 2–3/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 5–10 (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. + +```bash +# 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 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.** +```jsonc +{ + "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 `` parts) +The repo already proves the pattern in `CharacterStory.tsx` (`arm(ang,sign)` / `leg(sign,ang)` rotate `` groups by frame-derived angles). Replace the hand-drawn paths with vendored Humaaans part SVGs, keep the rig math: +```tsx +const f = useCurrentFrame(); +const wave = pose === "wave" ? 130 + Math.sin(f / 4) * 14 : 12; + + {/* vendored SVG , pivot at shoulder */} + + +``` +Keep conventions: `staticFile()` for raster, stable `rand(seed)` (not `Math.random`), per-instance `id()` prefixes (`cs${idn}_`) to avoid `` 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 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 (2–3 days).** Vendor Humaaans parts; build `` (separable `` arms/legs/head, pose presets) reusing the `CharacterStory.tsx` pose math. +- **Phase 2 — Layered scene system (2–3 days).** `` 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 (1–2 days).** Wire `colorSchema` → scene fills; verify studio colour controls recolor the whole stack. +- **Phase 4 — Lottie & motion polish (2 days).** Self-author 8–10 idle/wave/confetti/sky loops; integrate via `@remotion/lottie`; per-limb secondary motion + foreshortening on the hero (expressive hands). +- **Phase 5 — Persian/seasonal pack (1–2 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 7–8 | 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 | 2–3 | +| 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 | 5–6 | +| 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 ≈ 50–60** — and those need manual ``-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 `` 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 ~50–80 loops yet. +6. **Self-authored assets counted as if they exist** (Lottie ~50–80, 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`) — ~10–15 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 `` 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 3–5 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 + 2–3 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 **~30–40 character starter set** (Humaaans + IRA + DiceBear + Notion) split into riggable `` parts, plus a `` layered-scene system — enough to rebuild `CharacterStory` to the Alegria bar — then grow the roster to 100+ on that proven pipeline. diff --git a/services/remotion/package-lock.json b/services/remotion/package-lock.json index f5589a6..0af8491 100644 --- a/services/remotion/package-lock.json +++ b/services/remotion/package-lock.json @@ -12,6 +12,7 @@ "@react-three/fiber": "^9.1.2", "@react-three/postprocessing": "^3.0.4", "@remotion/cli": "4.0.290", + "@remotion/lottie": "^4.0.290", "@remotion/three": "^4.0.290", "@remotion/zod-types": "4.0.290", "@types/three": "^0.171.0", @@ -23,6 +24,8 @@ "zod": "3.22.3" }, "devDependencies": { + "@dicebear/collection": "^9.4.2", + "@dicebear/core": "^9.4.2", "@types/react": "19.0.0", "typescript": "5.5.4" } @@ -48,6 +51,468 @@ "node": ">=6.9.0" } }, + "node_modules/@dicebear/adventurer": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/adventurer/-/adventurer-9.4.2.tgz", + "integrity": "sha512-jqYp834ZmGDA9HBBDQAdgF1O2UTCwHF4vVrktXWa2Dppp1JczPL5HnVOWsjtrLmXNn61Wd6OLmBb2e6rhzp3ig==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/adventurer-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/adventurer-neutral/-/adventurer-neutral-9.4.2.tgz", + "integrity": "sha512-5xgkG/mNL4j3Q4SJGQLBU/KnU90tng8Ze5ofThD+55wi0oeY/nSAUowg6UFCmHrktjifj/MEx3CQqbpcPWtfIA==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/avataaars": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/avataaars/-/avataaars-9.4.2.tgz", + "integrity": "sha512-3x9jKFkOkFSPmpTbt9xvhiU2E1GX7beCSsX0tXRUShj8x6+5Ks9yBRT1VlkySbnXrZ/GglADGg7vJ/D2uIx1Yw==", + "dev": true, + "license": "See LICENSE file", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/avataaars-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/avataaars-neutral/-/avataaars-neutral-9.4.2.tgz", + "integrity": "sha512-/eNrp0YCNJRwQXqOloLm1+3Ss2C+pMpUQIGkbEnGsP1UK+13Ge80ggDDof1HpdqvG9HAZcKa7hnbG/0HSwyDSw==", + "dev": true, + "license": "See LICENSE file", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/big-ears": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/big-ears/-/big-ears-9.4.2.tgz", + "integrity": "sha512-mNfz3ppNA7UBq0IO3nXCiV5pFPG7c1DfzRB0foNU2Wo1XXT8FIcSY2BvDlYqorZTOUOz7dHb0vx06hqvG0HP5w==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/big-ears-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/big-ears-neutral/-/big-ears-neutral-9.4.2.tgz", + "integrity": "sha512-M8Ozmzza4eY4hpLOYULgJxMYmBA0CsBnrE15/xw6LZkEREXnrX5z0NJsf8hUfdyF6BWZ+RBgzoiav32DAC5zcg==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/big-smile": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/big-smile/-/big-smile-9.4.2.tgz", + "integrity": "sha512-hmT5i7rcPPhStjZyg28pbIhdTnnMBzK3RObI0vKCpY30EFrzaPkkdDL6Ck5fAFBdvDIW1EpOJkenyR0XPmhgbQ==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/bottts": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/bottts/-/bottts-9.4.2.tgz", + "integrity": "sha512-tsx+dII7EFUCVA8URj66G1GqORCCVduCAx4dY2prEY2IeFianVpkntXuFsWZ9BBGx1NZFndvDith5oTwKMQPbQ==", + "dev": true, + "license": "See LICENSE file", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/bottts-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/bottts-neutral/-/bottts-neutral-9.4.2.tgz", + "integrity": "sha512-kFNwWt6j+gzZ5n5Pz7WVwePubREAQOF8ZwWA9ztwVYDVMLnOChWbAofy5FED4j5md2MXFH2EgLCFCMr5K2BmIA==", + "dev": true, + "license": "See LICENSE file", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/collection": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/collection/-/collection-9.4.2.tgz", + "integrity": "sha512-KArubv7if8H7j9sIfpDK2hJJqrdNVR5zMPAMOSpIU2JPyXx8TC9o5wsmXb8il5wOHgaS9Q/cla7jUNIiDD7Gsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@dicebear/adventurer": "9.4.2", + "@dicebear/adventurer-neutral": "9.4.2", + "@dicebear/avataaars": "9.4.2", + "@dicebear/avataaars-neutral": "9.4.2", + "@dicebear/big-ears": "9.4.2", + "@dicebear/big-ears-neutral": "9.4.2", + "@dicebear/big-smile": "9.4.2", + "@dicebear/bottts": "9.4.2", + "@dicebear/bottts-neutral": "9.4.2", + "@dicebear/croodles": "9.4.2", + "@dicebear/croodles-neutral": "9.4.2", + "@dicebear/dylan": "9.4.2", + "@dicebear/fun-emoji": "9.4.2", + "@dicebear/glass": "9.4.2", + "@dicebear/icons": "9.4.2", + "@dicebear/identicon": "9.4.2", + "@dicebear/initials": "9.4.2", + "@dicebear/lorelei": "9.4.2", + "@dicebear/lorelei-neutral": "9.4.2", + "@dicebear/micah": "9.4.2", + "@dicebear/miniavs": "9.4.2", + "@dicebear/notionists": "9.4.2", + "@dicebear/notionists-neutral": "9.4.2", + "@dicebear/open-peeps": "9.4.2", + "@dicebear/personas": "9.4.2", + "@dicebear/pixel-art": "9.4.2", + "@dicebear/pixel-art-neutral": "9.4.2", + "@dicebear/rings": "9.4.2", + "@dicebear/shapes": "9.4.2", + "@dicebear/thumbs": "9.4.2", + "@dicebear/toon-head": "9.4.2" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/core": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/core/-/core-9.4.2.tgz", + "integrity": "sha512-MF0042+Z3s8PGZKZLySfhft28bUa3B1iq0e5NSjCvY8gfMi5aIH/iRJGRJa1N9Jz1BNkxYb4yvJ/N9KO8Z6Y+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@dicebear/croodles": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/croodles/-/croodles-9.4.2.tgz", + "integrity": "sha512-6VoO0JviIf7dKKMBTL/SMXxWhnXHaZuzufX90G0nXxS77ELG1YkGNMaZzawizN4C09Gbya2gJkozqrWiJN/aGw==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/croodles-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/croodles-neutral/-/croodles-neutral-9.4.2.tgz", + "integrity": "sha512-oG5IeUdtiYshQ89gkAVcl5w3xAEi5UZX2fTzIyelpBPCG176l7VuuFzlxi2umnB3E6LVHYy06DXvUo/p+rXB2Q==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/dylan": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/dylan/-/dylan-9.4.2.tgz", + "integrity": "sha512-1vQvRu9x9DrwFxhFaIU2rf0EUL04yDTbAt7fHyAjM0mEsKzTD4mRNf95tCRuavCoW6W48u7A/OY6jyIub6kxLQ==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/fun-emoji": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/fun-emoji/-/fun-emoji-9.4.2.tgz", + "integrity": "sha512-kqB6LPkdYCdEU/mwbyz34xLzoNUKL6ARcoo3fr5ASq9D6ZE07qIKybC3xv5+CPz7VmspJ1Q3c/VVWVMDRP7Twg==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/glass": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/glass/-/glass-9.4.2.tgz", + "integrity": "sha512-z5qUogHQ1b6UJ2zCqT848mU2U9DKbVDhiX6GPDjD7tYLisCCJVisH9p6WyNdHvflUd4SHkA6gRqVJIh2v2HnTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/icons": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/icons/-/icons-9.4.2.tgz", + "integrity": "sha512-QSMMz0NA03ypSGhXC8HQX8FSj8lYT+/5yqH+/N03OH2IjL0q7wwGZ7nqsrtlRp76O5WqMTwGfSbTUUYPjFr+Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/identicon": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/identicon/-/identicon-9.4.2.tgz", + "integrity": "sha512-JVDSmZsv11mSWqwAktK5x9Bslht2xY3TFUn8xzu6slAYe1Z7hEXZ76eb+UJ6F4qEzdwZ7xPWzAS6Nb0Y3A0pww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/initials": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/initials/-/initials-9.4.2.tgz", + "integrity": "sha512-yePuIUasmwtl9IrtB6rEzE/zb5fImKP/neW0CdcTC2MwLgMuP1GLHEGRgg1zI8exIh+PMv1YdLGyyUuRTE2Qpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/lorelei": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/lorelei/-/lorelei-9.4.2.tgz", + "integrity": "sha512-YMv6vnriW6VLFDsreKuOnUFFno6SRe7+7X7R7zPY0rZ+MaHX9V3jcioIG+1PSjIHEDfOLUHpr5vd1JBWv8y7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/lorelei-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/lorelei-neutral/-/lorelei-neutral-9.4.2.tgz", + "integrity": "sha512-yspanTthA5vh6iCdeLzn6xZ4yYMYRcfcxblcgSvHTF1ut0bjAXtw5SXzZ6aJTrJWiHkzYOQuTOR6GVYiW80Q7w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/micah": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/micah/-/micah-9.4.2.tgz", + "integrity": "sha512-e4D3W/OlChSsLo7Llwsy0J18vk0azJqF/uFoY+EKACCNHBc1HGNsqVvu2CTf+OWOA8wTyAK6UkjBN5p01r7D+g==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/miniavs": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/miniavs/-/miniavs-9.4.2.tgz", + "integrity": "sha512-wLwyFNNUnDRd3BbhSBhXR0XEpX8sG0/xDA5M/OkDoapLqZnnI48YLUSDd2N5QTAVMmcSEuZOYxkcnj7WW79vlg==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/notionists": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/notionists/-/notionists-9.4.2.tgz", + "integrity": "sha512-ZCySq+nxcD/x4xyYgytcj2N9uY3gxrL+qpnmOdp2BdA221KacVrxlsUPpIgEMqxS2rMmBQXfxg129Pzn4ycIpA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/notionists-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/notionists-neutral/-/notionists-neutral-9.4.2.tgz", + "integrity": "sha512-AyD9kEfVxQUwDGf4Op059gVmYIOAkTKg3dtE9h9mEKP7zl/kMy5B67BFFOo7sB0mXCjzAegZ6ekGU02E8+hIHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/open-peeps": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/open-peeps/-/open-peeps-9.4.2.tgz", + "integrity": "sha512-i01tLgtp2g937T81sVeAOVlqsCtiTck/Kw20g7hN80+7xrXjOUepz2HPLy3HeiMjwjMGRy5o54kSd0/8Ht4Dqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/personas": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/personas/-/personas-9.4.2.tgz", + "integrity": "sha512-NJlkvI5F5gugt6t2+7QrYNTwQC7+4IQZS3vG0dYk2BncxOHax0BuLovdSdiAesTL4ZkytFYIydWmKmV2/xcUwg==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/pixel-art": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/pixel-art/-/pixel-art-9.4.2.tgz", + "integrity": "sha512-peHf7oKICDgBZ8dUyj+txPnS7VZEWgvKE+xW4mNQqBt6dYZIjmva2shOVHn0b1JU+FDxMx3uIkWVixKdUq4WGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/pixel-art-neutral": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/pixel-art-neutral/-/pixel-art-neutral-9.4.2.tgz", + "integrity": "sha512-9e9Lz554uQvWaXV2P17ss+hPa6rTyuAKBtB8zk8ECjHiZzIl61N/KcTVLZ4dILVZwj7gYriaLo16QEqvL2GJCg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/rings": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/rings/-/rings-9.4.2.tgz", + "integrity": "sha512-Pc3ymWrRDQPJFNrbbLt7RJrzGvUuuxUiDkrfLhoVE+B6mZWEL1PC78DPbS1yUWYLErJOpJuM2GSwXmTbVjWf+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/shapes": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/shapes/-/shapes-9.4.2.tgz", + "integrity": "sha512-AFL6jAaiLztvcqyq+ds+lWZu6Vbp3PlGWhJeJRm842jxtiluJpl6r4f6nUXP2fdMz7MNpDzXfLooQK9E04NbUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/thumbs": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/thumbs/-/thumbs-9.4.2.tgz", + "integrity": "sha512-ccWvDBqbkWS5uzHbsg5L6uML6vBfX7jT3J3jHCQksvz8haHItxTK02w+6e1UavZUsvza4lG5X/XY3eji3siJ4Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, + "node_modules/@dicebear/toon-head": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/@dicebear/toon-head/-/toon-head-9.4.2.tgz", + "integrity": "sha512-lwFeSXyAnaKnCfMt9TiJwnD1cXQUGkey/0h6i/+4TVHVMCz5/Ri5u1ynovPNHy1SnBf858QwoXHkxilGLwQX/g==", + "dev": true, + "license": "(MIT AND CC-BY-4.0)", + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@dicebear/core": "^9.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", @@ -760,6 +1225,20 @@ "win32" ] }, + "node_modules/@remotion/lottie": { + "version": "4.0.290", + "resolved": "https://registry.npmjs.org/@remotion/lottie/-/lottie-4.0.290.tgz", + "integrity": "sha512-2wwPGs/RmUynF37mdhAIIXMw++uT7FbpTXv773mOoyMQf1VUq4J9XYpcewTm9nAIKIJhCF7D3l1FoZIrwIVqeQ==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "remotion": "4.0.290" + }, + "peerDependencies": { + "lottie-web": "^5", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@remotion/media-parser": { "version": "4.0.290", "resolved": "https://registry.npmjs.org/@remotion/media-parser/-/media-parser-4.0.290.tgz", @@ -2106,6 +2585,13 @@ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "license": "MIT" }, + "node_modules/lottie-web": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.13.0.tgz", + "integrity": "sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ==", + "license": "MIT", + "peer": true + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", diff --git a/services/remotion/package.json b/services/remotion/package.json index a137130..8b666dc 100644 --- a/services/remotion/package.json +++ b/services/remotion/package.json @@ -7,13 +7,16 @@ "dev": "remotion studio", "render": "remotion render", "still": "remotion still", - "upgrade": "remotion upgrade" + "upgrade": "remotion upgrade", + "gen:dicebear": "node scripts/gen-dicebear.mjs", + "check:assets": "node scripts/check-assets.mjs" }, "dependencies": { "@react-three/drei": "^10.7.7", "@react-three/fiber": "^9.1.2", "@react-three/postprocessing": "^3.0.4", "@remotion/cli": "4.0.290", + "@remotion/lottie": "^4.0.290", "@remotion/three": "^4.0.290", "@remotion/zod-types": "4.0.290", "@types/three": "^0.171.0", @@ -25,6 +28,8 @@ "zod": "3.22.3" }, "devDependencies": { + "@dicebear/collection": "^9.4.2", + "@dicebear/core": "^9.4.2", "@types/react": "19.0.0", "typescript": "5.5.4" } diff --git a/services/remotion/public/illustrations/assets.json b/services/remotion/public/illustrations/assets.json new file mode 100644 index 0000000..bc95345 --- /dev/null +++ b/services/remotion/public/illustrations/assets.json @@ -0,0 +1,362 @@ +{ + "dicebear/openpeeps-01.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-1'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-02.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-2'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-03.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-3'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-04.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-4'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-05.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-5'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-06.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-6'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-07.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-7'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-08.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-8'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-09.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-9'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-10.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-10'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-11.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-11'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-12.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-12'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-13.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-13'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-14.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-14'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-15.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-15'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-16.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-16'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-17.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-17'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-18.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-18'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-19.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-19'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-20.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-20'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-21.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-21'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-22.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-22'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-23.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-23'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-24.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-24'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-25.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-25'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-26.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-26'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-27.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-27'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-28.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-28'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-29.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-29'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + }, + "dicebear/openpeeps-30.svg": { + "source": "DiceBear open-peeps (Pablo Stanley Open Peeps)", + "license": "CC0-1.0", + "license_class": "CC0", + "commercial_ok": true, + "attribution_required": false, + "ai_training_allowed": true, + "animation_fit": "swap-transform (bust/half-body micro-rig)", + "generator": "createAvatar(openPeeps,{seed:'flatrender-peep-30'})", + "url": "https://www.dicebear.com/styles/open-peeps/", + "vendored": "2026-06-22" + } +} diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-01.svg b/services/remotion/public/illustrations/dicebear/openpeeps-01.svg new file mode 100644 index 0000000..9a76dc4 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-01.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-02.svg b/services/remotion/public/illustrations/dicebear/openpeeps-02.svg new file mode 100644 index 0000000..00b2f1d --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-02.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-03.svg b/services/remotion/public/illustrations/dicebear/openpeeps-03.svg new file mode 100644 index 0000000..89ce213 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-03.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-04.svg b/services/remotion/public/illustrations/dicebear/openpeeps-04.svg new file mode 100644 index 0000000..e6672ce --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-04.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-05.svg b/services/remotion/public/illustrations/dicebear/openpeeps-05.svg new file mode 100644 index 0000000..3ae2681 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-05.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-06.svg b/services/remotion/public/illustrations/dicebear/openpeeps-06.svg new file mode 100644 index 0000000..73a70a2 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-06.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-07.svg b/services/remotion/public/illustrations/dicebear/openpeeps-07.svg new file mode 100644 index 0000000..59f2ecd --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-07.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-08.svg b/services/remotion/public/illustrations/dicebear/openpeeps-08.svg new file mode 100644 index 0000000..7a60027 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-08.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-09.svg b/services/remotion/public/illustrations/dicebear/openpeeps-09.svg new file mode 100644 index 0000000..447d4dd --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-09.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-10.svg b/services/remotion/public/illustrations/dicebear/openpeeps-10.svg new file mode 100644 index 0000000..11a422b --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-10.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-11.svg b/services/remotion/public/illustrations/dicebear/openpeeps-11.svg new file mode 100644 index 0000000..22dfdaf --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-11.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-12.svg b/services/remotion/public/illustrations/dicebear/openpeeps-12.svg new file mode 100644 index 0000000..eef5d01 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-12.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-13.svg b/services/remotion/public/illustrations/dicebear/openpeeps-13.svg new file mode 100644 index 0000000..4ddf203 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-13.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-14.svg b/services/remotion/public/illustrations/dicebear/openpeeps-14.svg new file mode 100644 index 0000000..ceee477 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-14.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-15.svg b/services/remotion/public/illustrations/dicebear/openpeeps-15.svg new file mode 100644 index 0000000..0ce776e --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-15.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-16.svg b/services/remotion/public/illustrations/dicebear/openpeeps-16.svg new file mode 100644 index 0000000..daf76f0 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-16.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-17.svg b/services/remotion/public/illustrations/dicebear/openpeeps-17.svg new file mode 100644 index 0000000..edbd6df --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-17.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-18.svg b/services/remotion/public/illustrations/dicebear/openpeeps-18.svg new file mode 100644 index 0000000..61320b5 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-18.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-19.svg b/services/remotion/public/illustrations/dicebear/openpeeps-19.svg new file mode 100644 index 0000000..c7377d3 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-19.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-20.svg b/services/remotion/public/illustrations/dicebear/openpeeps-20.svg new file mode 100644 index 0000000..9da1203 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-20.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-21.svg b/services/remotion/public/illustrations/dicebear/openpeeps-21.svg new file mode 100644 index 0000000..ea2414d --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-21.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-22.svg b/services/remotion/public/illustrations/dicebear/openpeeps-22.svg new file mode 100644 index 0000000..e7ba956 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-22.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-23.svg b/services/remotion/public/illustrations/dicebear/openpeeps-23.svg new file mode 100644 index 0000000..39f8667 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-23.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-24.svg b/services/remotion/public/illustrations/dicebear/openpeeps-24.svg new file mode 100644 index 0000000..8d3aa4a --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-24.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-25.svg b/services/remotion/public/illustrations/dicebear/openpeeps-25.svg new file mode 100644 index 0000000..f3a211c --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-25.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-26.svg b/services/remotion/public/illustrations/dicebear/openpeeps-26.svg new file mode 100644 index 0000000..0274a91 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-26.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-27.svg b/services/remotion/public/illustrations/dicebear/openpeeps-27.svg new file mode 100644 index 0000000..31e9992 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-27.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-28.svg b/services/remotion/public/illustrations/dicebear/openpeeps-28.svg new file mode 100644 index 0000000..b7ed067 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-28.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-29.svg b/services/remotion/public/illustrations/dicebear/openpeeps-29.svg new file mode 100644 index 0000000..ace1e20 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-29.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/public/illustrations/dicebear/openpeeps-30.svg b/services/remotion/public/illustrations/dicebear/openpeeps-30.svg new file mode 100644 index 0000000..9d7cac7 --- /dev/null +++ b/services/remotion/public/illustrations/dicebear/openpeeps-30.svg @@ -0,0 +1 @@ +Open PeepsPablo Stanleyhttps://www.openpeeps.com/https://creativecommons.org/publicdomain/zero/1.0/Remix of „Open Peeps” (https://www.openpeeps.com/) by „Pablo Stanley”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/services/remotion/scripts/check-assets.mjs b/services/remotion/scripts/check-assets.mjs new file mode 100644 index 0000000..1af3e1c --- /dev/null +++ b/services/remotion/scripts/check-assets.mjs @@ -0,0 +1,41 @@ +// License-firewall CI guard. +// +// Every vendored asset under public/illustrations/ (and public/lottie/) MUST have a +// row in public/illustrations/assets.json. No row -> the asset may not ship. Fails +// the build (exit 1) on any un-ledgered file. Run: npm run check:assets +import { readFileSync, readdirSync, statSync, existsSync } from "node:fs"; +import { join, dirname, relative } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const PUBLIC = join(__dirname, "..", "public"); +const ILLUS = join(PUBLIC, "illustrations"); +const ledgerPath = join(ILLUS, "assets.json"); + +if (!existsSync(ledgerPath)) { + console.error(`MISSING license ledger: ${ledgerPath}`); + process.exit(1); +} +const ledger = JSON.parse(readFileSync(ledgerPath, "utf8")); + +function walk(dir) { + if (!existsSync(dir)) return []; + let out = []; + for (const e of readdirSync(dir)) { + const p = join(dir, e); + if (statSync(p).isDirectory()) out = out.concat(walk(p)); + else if (/\.(svg|json)$/i.test(e) && e !== "assets.json") out.push(p); + } + return out; +} + +// Asset files live under illustrations// and lottie/. +const files = [...walk(ILLUS), ...walk(join(PUBLIC, "lottie"))] + .map((p) => relative(ILLUS, p).split("\\").join("/")); + +const missing = files.filter((f) => !ledger[f]); +if (missing.length) { + console.error(`Un-ledgered assets (add a row to assets.json):\n ${missing.join("\n ")}`); + process.exit(1); +} +console.log(`assets.json OK — ${files.length} vendored asset(s), all ledgered.`); diff --git a/services/remotion/scripts/gen-dicebear.mjs b/services/remotion/scripts/gen-dicebear.mjs new file mode 100644 index 0000000..9a88c90 --- /dev/null +++ b/services/remotion/scripts/gen-dicebear.mjs @@ -0,0 +1,53 @@ +// Build-time character generator. +// +// DiceBear's `open-peeps` style IS Pablo Stanley's Open Peeps artwork (CC0-1.0). +// We generate deterministic per-seed SVGs OFFLINE (no runtime CDN / HTTP call) and +// vendor them into public/illustrations/dicebear/, then write a license-ledger row +// per file into public/illustrations/assets.json. Run: npm run gen:dicebear +import { createAvatar } from "@dicebear/core"; +import { openPeeps } from "@dicebear/collection"; +import { writeFileSync, readFileSync, mkdirSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const ILLUS = join(__dirname, "..", "public", "illustrations"); +const OUT = join(ILLUS, "dicebear"); +mkdirSync(OUT, { recursive: true }); + +const COUNT = 30; +const VENDORED = "2026-06-22"; +const ledger = {}; + +for (let i = 1; i <= COUNT; i++) { + const seed = `flatrender-peep-${i}`; + // idRandomizer keeps SVG ids unique so multiple avatars can be inlined + // in one document without clashing (Remotion composites many in one frame). + const svg = createAvatar(openPeeps, { seed, size: 400, randomizeIds: true }).toString(); + const file = `openpeeps-${String(i).padStart(2, "0")}.svg`; + writeFileSync(join(OUT, file), svg, "utf8"); + ledger[`dicebear/${file}`] = { + source: "DiceBear open-peeps (Pablo Stanley Open Peeps)", + license: "CC0-1.0", + license_class: "CC0", + commercial_ok: true, + attribution_required: false, + ai_training_allowed: true, + animation_fit: "swap-transform (bust/half-body micro-rig)", + generator: `createAvatar(openPeeps,{seed:'${seed}'})`, + url: "https://www.dicebear.com/styles/open-peeps/", + vendored: VENDORED, + }; +} + +// Merge into the assets.json license ledger (preserve any existing rows). +const ledgerPath = join(ILLUS, "assets.json"); +let existing = {}; +try { + existing = JSON.parse(readFileSync(ledgerPath, "utf8")); +} catch { + existing = {}; +} +writeFileSync(ledgerPath, JSON.stringify({ ...existing, ...ledger }, null, 2) + "\n", "utf8"); +console.log(`generated ${COUNT} open-peeps SVGs in ${OUT}`); +console.log(`ledger now has ${Object.keys({ ...existing, ...ledger }).length} rows`); diff --git a/services/remotion/src/Root.tsx b/services/remotion/src/Root.tsx index ecc2ed4..107989b 100644 --- a/services/remotion/src/Root.tsx +++ b/services/remotion/src/Root.tsx @@ -2,6 +2,7 @@ import { Composition } from "remotion"; import { ASPECTS } from "./lib/aspect"; import { TEMPLATES } from "./templates"; import { Three3DTest } from "./compositions/Three3DTest"; +import { AssetSheet } from "./compositions/AssetSheet"; import { IlluminatedCircles, illuminatedCirclesSchema, @@ -113,6 +114,16 @@ export const RemotionRoot: React.FC = () => { height={720} /> + {/* Dev preview: vendored CC0 character library (not a customer template) */} + + {/* 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 diff --git a/services/remotion/src/compositions/AssetSheet.tsx b/services/remotion/src/compositions/AssetSheet.tsx new file mode 100644 index 0000000..753c538 --- /dev/null +++ b/services/remotion/src/compositions/AssetSheet.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import { AbsoluteFill, Img, staticFile } from "remotion"; +import { FONT } from "../lib/fonts"; + +// Dev/preview composition (NOT a customer template — registered standalone in Root, +// never seeded). Renders a contact-sheet of the vendored CC0 Open-Peeps characters +// to verify the public/illustrations -> staticFile() -> render pipeline works. +const COUNT = 30; + +export const AssetSheet: React.FC = () => { + const items = Array.from({ length: COUNT }, (_, i) => + `illustrations/dicebear/openpeeps-${String(i + 1).padStart(2, "0")}.svg` + ); + return ( + +
+ کتابخانهٔ شخصیت‌ها — Open Peeps (CC0) ۳۰ نمونه +
+
+ {items.map((src, i) => ( +
+ +
+ ))} +
+
+ ); +};