/motion studio roadmap

Check items off as they ship. Progress is saved in your browser. Sprint 1 (items 1–5) is complete; sprint 2 (terminal) is done. Items 11–22 track parity with Fluid — shaders, distortion, and distribution — without changing core studio behaviour until each ships.

← back to studio · updated June 2026 · ref fluid dev docs · see also docs/PLAN.md

Recently shipped

settings persistence undo / redo preset thumbnails export progress UI Monaco GLSL editor terminal tabs + reconnect chromaverse: gallery font diet chromaverse: firebase cache headers chromaverse: card content-visibility chromaverse: deferred banner shader

Next up — studio polish (items 6–10)

6 · terminal

Multiple shell tabs, spawn/kill, and a clear “PTY server offline” banner with reconnect. One command: npm run studio (Vite + PTY together).

7 · text layers

Sidebar list of all text elements: duplicate, reorder, lock, hide. Snap to center and rule-of-thirds guides.

8 · animation

Per-text entrance presets (fade, slide, scale, typewriter) keyed to u_phase — seamless by default.

9 · curation

Pin presets, recent list, fuzzy palette in command palette. Randomize palette-only / sliders-only / locked sliders.

10 · compositing

Position, scale, rotation for uploaded images. Optional luminance-driven shader modulation.

Fluid parity — distribution & services (items 11–14)

Fluid ships embeds, an MCP server, and a no-auth REST API on top of the same client-side renderer. We already have share URLs and self-contained HTML export — these close the gap for agents and third-party sites.

11 · embed sdk

npm i lumen-bg + React <LumenBg/>. Copy-paste snippets: responsive iframe, full-bleed fixed background (pointer-events:none), and static CSS from exported PNG. Hash carries full state — canvas-only, no hosting.

12 · agent api

HTTP MCP: create_piece, list_looks, decode_link. Plain JSON /api/piece — same params as share URLs, no key. “Code for Claude” panel copies a ready-made prompt + embed block.

13 · curation

Curated looks (named starting points via API). Gallery page: pieces rendered live in-browser, filter by engine preset and vibe. Tap to open in studio and remix.

14 · library

Persist saved pieces locally (IndexedDB): thumbnail, name, timestamp. Quick reload without losing the current session. Complements auto-save in Phase 1.

Fluid parity — fields, melt & surface (items 15–18)

Fluid’s Field step has 12 engines; our u_distort slider modulates presets but we lack several engines and a dedicated surface post-pass. Source images “melt” via liquify + luminance-driven shape.

15 · fields

Port Fluid engines we lack: cellular, gyroid, smoke, crystal, honeycomb, grid. Revisit interfere / golden as optional phyllotaxis mode. All loop-safe via u_phase + loopOff().

16 · source melt

GPU-only image ingest (file + camera). Liquify warps the field; photo blend mixes luminance into shape while palette owns colour. Built-in melt textures, flip, freeze, center. Extends item 10.

17 · surface

Second-pass screen treatment after the field: pixelate, dot size, threshold. Screen modes: square, hex, ASCII, dither, halftone — toggles on top of any preset, not baked per-mode.

18 · warp

Split warp (domain displacement strength, Fluid 0–9) from distort (preset modulation). Add symmetry slider — bilateral / radial mirror of the field. Pair with zoom alias for scale.

Fluid parity — UX & interaction (items 19–22)

19 · text

Glyphs filled with the animated shader (mask / clip), not flat colour. Dark or light letter background. Banner-friendly wide aspect presets.

20 · preview

Canvas chrome: Live / Still toggle (pause loop without hiding UI). Before / after split or wipe comparing params snapshot vs current — useful for randomize and melt tweaks.

21 · input

Optional pointer-driven distortion: move cursor over canvas to ripple the field (Fluid’s “random pattern — move your cursor”). Phase-looped fallback when idle; disable for export.

22 · colours

Four-stop dark→light gradient UI (Fluid Custom palette). Named palette presets stay; custom stops sync to share URL and API. One-click Record clip beside PNG export.

Chromaverse — gallery performance (items 23–34)

The gallery ships as a ~1 MB monolith: 65 pre-rendered cards, 400 KB inline JSON, and (formerly) 65 Google Font requests. Items 23–26 are quick wins; 27–34 are the structural fixes.

23 · fonts

Load only Inter + JetBrains Mono on the gallery index. Theme fonts load on individual theme pages — not 65 <link> tags on first paint.

24 · hosting

Cache-Control on /assets/** (immutable), /chromaverse/** (1 h + stale-while-revalidate), and theme HTML (5 min).

25 · render

Skip layout/paint for off-screen theme cards. contain-intrinsic-size preserves scroll height without mounting 65 dual-preview panels at once.

26 · gpu

Start the banner WebGL loop only when the hero enters the viewport (IntersectionObserver + 120px root margin). Saves GPU on studio-first visits.

27 · data

Move ALL_THEMES_DATA (~400 KB) out of inline HTML into a cacheable JSON file fetched on demand.

28 · dom

Generate the 65-card grid from JSON instead of shipping ~355 KB of duplicated pre-rendered HTML in the page.

29 · fonts

Inject per-theme Google Font <link> tags only for cards entering the viewport — live Aa previews without eager loading all families.

30 · builder

Lazy-load the ~72 KB builder <template> and its JS until the user opens Theme Builder Studio.

31 · scroll

Mount/unmount card DOM nodes based on scroll position — pairs with item 28 for large theme counts.

32 · fonts

If eager loading returns, merge families into 1–2 combined css2 URLs instead of dozens of separate <link> tags.

33 · fonts

Bundle Inter + JetBrains Mono as local WOFF2 — drop Google DNS/TLS from the critical path.

34 · assets

Extract gallery styles to chromaverse/gallery.css — cache separately from HTML, smaller repeat-visit payload.

Phase 1 — studio shell (3–6 months)

infrastructure

  • .lumen manifest — single source of truth: params, texts, custom shader, layout, export prefs
  • Auto-save — IndexedDB snapshots + crash recovery prompt
  • Export queue — batch PNG + WebM + GIF with shared progress panel

Milestone: self-contained creative sandbox that feels like a native app.

extensibility

  • Manifest: preset id, icon, slider defs, GLSL branch
  • Hot-load plugins without editing webgl.ts core
  • Example third-party preset in examples/

Phase 2 — timeline & layers (6–12 months)

composition

  • Shader, text, image, solid, video layers with z-order
  • Per-layer transform: position, scale, rotation, opacity
  • Blending modes + adjustment layers
  • Pre-compositions (nest comps inside comps)

Milestone: compose generative shaders over video with animated text — a real motion tool.

animation

  • Visual keyframes per property on a timeline track
  • Linear + bezier interpolation, graph editor for curves
  • All motion respects seamless loop invariant

Phase 3 — node graph (12–18 months)

hybrid paradigm

  • Every layer gets a Caddis-style node graph
  • 50+ built-in nodes: color, blur, distort, matte, generate
  • Custom GLSL as a node with typed ports
  • JavaScript expressions on any parameter (AE-style)
  • Community preset browser for node setups

Milestone: compositing expressiveness rivaling Fusion/Cavalry with layer approachability.

Phase 4 — platform (18–24 months)

distribution

  • Plugin marketplace — presets, node packs, themes
  • Real-time multiplayer editing (Figma-style cursors + sync)
  • Data-driven animation from CSV/JSON/Sheets
  • Interactive export runtime (Rive-style state machines)
  • Audio-reactive parameters via spectrum analysis
  • AI utility nodes (depth, segmentation, upscale) via ONNX/WASM

Milestone: open-source motion design platform — create, collaborate, distribute.

Technical evolution

  • Rendering — WebGPU primary, WebGL2 fallback; WGSL/GLSL transpile path
  • Desktop — Tauri wrapper for native FS, file associations, smaller binary than Electron
  • State — MobX or Zustand for reactive param graph as complexity grows
  • Testing — automated loop-seam pixel diff; shader compile regression suite
  • Resilience — WebGL context loss recovery; pause-when-hidden for laptop battery