Skip to content

Build a card out of blocks when no preset is its shape - #217

Merged
nmbrthirteen merged 1 commit into
mainfrom
dynamic-cards
Sep 6, 2026
Merged

Build a card out of blocks when no preset is its shape#217
nmbrthirteen merged 1 commit into
mainfrom
dynamic-cards

Conversation

@nmbrthirteen

@nmbrthirteen nmbrthirteen commented Sep 6, 2026

Copy link
Copy Markdown
Owner

The card kinds are eight layouts somebody drew in advance, and a moment that
is not a figure, a list or a quote got the nearest one worn the wrong way
round or nothing at all. The moments that came out worst are the ones with
nothing in them a camera could point at: a system seizing up, ten years
compressed into a phrase, trust eroding. A talking head carries those least
well and there is no figure in them to hang a preset on, so they were skipped.

scene is the ninth kind and the one with no shape of its own: a layout and
a list of blocks. text, quote, list, bars, meter, steps, chip, media, rule,
and group to nest them side by side. Fourteen blocks, three deep. The set is
closed on purpose — unlimited arrangements, not unlimited marks, because a
plan that can name its own shapes can draw something nobody in the show would
sign off.

An arrangement nobody has seen before does not know how tall it is, which
every preset did because a person sized it. So it is measured: wrapping is
estimated from the advance width rather than laid out, because the same
number has to come out in a browser preview and in a headless render and only
one of those can measure text before it lays out. Media gives up its band
first, down to the height below which a picture says nothing, and only then
does the type scale — a picture cropped tighter is still the picture, where
type shrunk to fit one is a card nobody reads at arm's length. The shrink has
a floor of 0.55; a scene that would go past it takes the whole frame rather
than sharing it with the speaker at a size that reads as a mistake.

Older plans are untouched: the eight presets draw exactly what they drew, and
an engine that has never heard of scene already drops a kind it cannot draw
rather than painting an empty slab over the speaker.

Summary by CodeRabbit

  • New Features
    • Added flexible scene cards supporting custom content arrangements, including text, quotes, lists, charts, meters, steps, chips, dividers, groups, and media.
    • Added stack, row, and grid layouts with configurable spacing and alignment.
    • Scenes automatically adapt typography and media sizing to fit available space.
    • Added support for video and image content within scenes.
  • Bug Fixes
    • Improved card selection and sizing behavior for scene-based content.

The card kinds are eight layouts somebody drew in advance, and a moment that
is not a figure, a list or a quote got the nearest one worn the wrong way
round or nothing at all. The moments that came out worst are the ones with
nothing in them a camera could point at: a system seizing up, ten years
compressed into a phrase, trust eroding. A talking head carries those least
well and there is no figure in them to hang a preset on, so they were skipped.

`scene` is the ninth kind and the one with no shape of its own: a layout and
a list of blocks. text, quote, list, bars, meter, steps, chip, media, rule,
and group to nest them side by side. Fourteen blocks, three deep. The set is
closed on purpose — unlimited arrangements, not unlimited marks, because a
plan that can name its own shapes can draw something nobody in the show would
sign off.

An arrangement nobody has seen before does not know how tall it is, which
every preset did because a person sized it. So it is measured: wrapping is
estimated from the advance width rather than laid out, because the same
number has to come out in a browser preview and in a headless render and only
one of those can measure text before it lays out. Media gives up its band
first, down to the height below which a picture says nothing, and only then
does the type scale — a picture cropped tighter is still the picture, where
type shrunk to fit one is a card nobody reads at arm's length. The shrink has
a floor of 0.55; a scene that would go past it takes the whole frame rather
than sharing it with the speaker at a size that reads as a mistake.

Older plans are untouched: the eight presets draw exactly what they drew, and
an engine that has never heard of `scene` already drops a kind it cannot draw
rather than painting an empty slab over the speaker.
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 3c5897bf-3042-4990-98d9-02067444aa4b

📥 Commits

Reviewing files that changed from the base of the PR and between bb2ab27 and aca6945.

📒 Files selected for processing (6)
  • remotion/src/cards.ts
  • remotion/src/components/Cards.tsx
  • remotion/src/components/Scene.tsx
  • remotion/src/components/brand.ts
  • remotion/src/scene.test.ts
  • remotion/src/scene.ts

📝 Walkthrough

Walkthrough

Adds a typed "scene" card variant with nested block layouts. Implements scene measurement, adaptive fitting, rendering, brand utilities, card validation, speaker-sharing decisions, and unit tests.

Changes

Scene card model and measurement

Layer / File(s) Summary
Scene model and measurement
remotion/src/scene.ts, remotion/src/cards.ts
Defines scene block types, layout options, measurement constants, recursive height calculations, fit scaling, media detection, block counting, and the "scene" card variant.

Scene rendering

Layer / File(s) Summary
Scene rendering and fitting
remotion/src/components/Scene.tsx
Renders text, quotes, lists, charts, meters, steps, chips, media, rules, and groups. Supports stack, row, and grid layouts. Fits media and typography to the available room.

Card integration

Layer / File(s) Summary
Card integration and brand utilities
remotion/src/components/Cards.tsx, remotion/src/components/brand.ts
Moves brand values and color helpers into a shared module. Registers scene cards, filters empty scenes, renders Scene, and limits speaker sharing when the scene fit falls below MIN_FIT.

Validation

Layer / File(s) Summary
Scene behavior tests
remotion/src/scene.test.ts
Tests scene fitting, wrapped text measurement, row sizing, nested block inspection, media detection, and half-open card timing.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CardTimeline
  participant Cards
  participant fitScene
  participant Scene
  participant RemotionMedia
  CardTimeline->>Cards: select active scene card
  Cards->>fitScene: evaluate available room
  fitScene-->>Cards: return fit and media height
  Cards->>Scene: render fitted blocks
  Scene->>RemotionMedia: render video or image blocks
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dynamic-cards

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nmbrthirteen
nmbrthirteen merged commit 0c4f822 into main Sep 6, 2026
13 of 14 checks passed
@nmbrthirteen nmbrthirteen mentioned this pull request Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant