Skip to content

Explore seven Open Graph image and video concepts - #185

Draft
jonbeckman wants to merge 1 commit into
masterfrom
cursor/og-image-concepts-338e
Draft

jonbeckman wants to merge 1 commit into
masterfrom
cursor/og-image-concepts-338e

Conversation

@jonbeckman

Copy link
Copy Markdown
Contributor

Summary

This is an exploration of seven Open Graph stills and five-second loops for the web app. It stays a draft until a direction is chosen. Drafts do not run CI.

Nothing here is wired into the served app, so there is no user-visible change. The pull request uses release:none for that reason. Please leave it in draft.

The scenes live in apps/web/src/creative/og/ and render with the same Takumi native binding as the release cards (nub run creative:og). Components stay free of file access so they can later run through takumi-js/wasm. This pull request does not add Worker support.

Takumi APIs used, rather than a custom animator: Renderer.render() with timeMs, Renderer.renderAnimation() for GIF, and CSS @keyframes carried in the component tree. Video frames are raw RGBA piped to ffmpeg, which is the video path in Takumi's keyframe guide. The guide's example uses Bun's spawn. This repo runs on Node, so the same pipe uses node:child_process.

Custom code, and why no native API covered it:

  • Kumo tokens are read from @cloudflare/kumo theme-kumo.css and apps/web/src/styles/app.css, then passed as custom properties. Takumi does not run the Tailwind or Kumo pipeline.
  • The logo SVG fill is converted from the Kumo oklch() token to hex. An oklch() fill in the SVG painted black.
  • The mark is split with overflow panes. clip-path on the SVG image also painted black.
  • The landing shader is approximated. Takumi has no WebGL runtime, so it cannot run Paper's GemSmoke shader.

Each loop holds the poster from 0–6% and 94–100% of the timeline. renderAnimation() samples the open interval before the duration, so the last frame falls inside that hold and matches the first. Raw first and last frames were compared while iterating. That comparison is not in the repo or CI.

Contact sheet

1. In use

A stylized composer, not a screen recording. The home placeholder and "Preparing Isolate agent..." sit on a Kumo elevated card. A brand line shrinks and the status fades, then both return.

Reuses the SolZero logo, Manrope, Kumo canvas, elevated, brand, and line tokens, homeComposerPlaceholder, and homePreparingAgentLabel with the Isolate runtime label.

Loops by returning the line and the status to the opening card. The still is that card.

2. Landing smoke

The home hero: GemSmoke colors inside the mark, "Welcome to SolZero", and "Chat, build, and automate with project context".

Reuses solzeroGemSmokeColors from the animated icon, the logo as a mask, the welcome heading, and the composer placeholder.

Blue radial gradients drift and return to the same places. The color inside the mark shifts and returns. Takumi cannot run the Paper shader, so this is a CSS gradient and blur approximation of those three colors, not a captured shader frame.

3. Done

The outcome, with a feeling of relief. A success-colored check, the word "Done.", and the README tagline "Give your work an agent." A green glow breathes and settles.

Reuses the README line under the title, Kumo success, and Manrope.

The glow scale and opacity are the same at the start and the end.

4. Chat, build, automate

A three-beat story taken from the composer placeholder: Chat, then Build, then Automate, then Chat again. One word is large. Dots mark the beat.

Reuses the placeholder words, the logo lockup, and the brand color for the active dot.

Each word is fully opaque only in its own window, and the first and last windows are Chat, so the words do not stack and the loop closes.

5. Agents, workflows, bots

A fixed promise on the left and one product surface on the right. The surfaces are the sidebar labels. The left side does not move.

Reuses primaryNavLabels and the README tagline.

The right-hand word crossfades and the opening word, Agents, is back before the last frame.

6. Workflow loop

A dot travels a closed rectangle through four real workflow nodes: Webhook, Isolate Agent, User Approval, and Email.

Reuses those labels from WORKFLOW_NODE_CATALOG, the Workflows nav label, and Takumi offset-path / offset-distance.

The path is closed. The dot rests on the start corner at both ends of the timeline, which is the same point as the end of the lap.

7. The mark

The loader's four pieces leave and come back together. The still is the whole mark.

Reuses LOADER_PIECES, the loader stagger, and the assembly and departure duration ratio from s0-loader-motion.ts, plus the logo SVG. Travel distance is scaled up from the icon-sized offsets so the split reads at 1200 pixels. The pieces stay opaque. The loader fades them out, which disappeared at this size. GSAP power2 is not available in Takumi, so the segments use ease-in and ease-out.

The pieces are home, and fully visible, at both ends.

Recommendation

  1. Landing smoke. It is the brand card. The welcome line and the composer line are readable at thumbnail size, the mark is recognizable, and the motion stays behind the type. It is the closest of the seven to a link preview someone would post.
  2. Done. It is the feeling card. "Done." and the check survive a tiny crop, and the README line says what SolZero is when the video does not play. The glow is a simple loop with no UI to misread.

Agents, workflows, bots is the next choice if the preview should show range instead of a feeling.

Validation

  • nub run config:check
  • nub run typecheck
  • nub run lint
  • nub run format
  • Rendered all seven concepts with nub run creative:og and inspected the stills, mid-loop frames, and the contact sheet. Raw first and last frames matched during iteration.
  • nub run test was not run. The e2e suite drives the app. This change does not alter a user flow, and the visible strings are unchanged. The proof is the rendered frames.

Checklist

  • I added or updated tests for behavior changes, or explained why tests are not needed.
  • I updated documentation and config examples when behavior or configuration changed.
  • I added a .tegami/ release entry, or explained why this pull request uses release:none.
  • I ran nub run config:check, nub run typecheck, nub run lint, nub run format, and nub run test.
  • I did not include credentials, private data, internal URLs, or organization-specific defaults.
  • I updated THIRD_PARTY_NOTICES.md for new third-party code or separately licensed assets.
Open in Web Open in Cursor 

Render stills and seamless loops with Takumi from the app's logo, type, and Kumo tokens so a direction can be chosen before any of them ship.

Co-authored-by: Jonathan Beckman <jonathantbeckman@gmail.com>
@jonbeckman jonbeckman added the release:none label Nov 9, 2026 — with Cursor

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants