card-motion
Use when a card should animate: elements entering and leaving, a list or grid rearranging, a tile opening into a detail view, drag and reorder, scroll-linked…
Skill by cardstack
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/cardstack-card-motion
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: writing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/card-motion
What's inside
- Skill name
card-motion- Description
- Use when a card should animate: elements entering and leaving, a list or grid rearranging, a tile opening into a detail view, drag and reorder, scroll-linked effects, or several elements moving in a sequenced scene. Covers which of glimmer-motion's patterns to reach for ({{motion}}, <Presence>, layout / layoutId, drag and <ReorderGroup>, scrollProgress / InView) and when to escalate to a <Choreo> timeline, the imports a realm can resolve (motion-dom only through glimmer-motion), the three Glimmer rules that silently stop motion, and the card-specific rules that follow from cards sharing the host's copy of both libraries. Activates on glimmer-motion, @cardstack/choreo, {{motion}}, Presence, layoutId, Choreo, "animate", "transition", "enter/exit animation", "reorder", "parallax", "magic move".
- License
- MIT
- Instructions
- 98 lines in SKILL.md · view on GitHub
Files (9)
- SKILL.md
- choreo.md · references/
- drag-and-reorder.md · references/
- element.md · references/
- layout.md · references/
- presence.md · references/
- scroll.md · references/
- testing.md · references/
- view-transitions.md · references/
SKILL.md (first lines)
# Animating a card
_glimmer-motion animates elements; Choreo sequences a whole render pass. Both come from the host — nothing to install._
```gts
import { CardDef, Component } from '@cardstack/base/card-api';
import { motion, spring, to } from 'glimmer-motion';
const soft = spring({ visualDuration: 0.4, bounce: 0.2 });
export class Notice extends CardDef {
static isolated = class Isolated extends Component<typeof this> {
<template>
<article
{{motion
initial=(to opacity=0 y=12)
animate=(to opacity=1 y=0)
transition=soft
}}
>
<@fields.cardTitle />
</article>
</template>
};
}
```
## What a realm can import
The host hands cards its own copies of both libraries through its module shims:
| Specifier | What it is |
| --- | --- |
| `glimmer-motion` | The `{{motion}}` modifier, `<Presence>`, `<LayoutGroup>`, `<MotionConfig>`, `<ReorderGroup>` / `<ReorderItem>`, the `to` / `spring` / `tween` / `stagger` / `styles` helpers, `scrollProgress`, `InView`, `viewTransition`, and the engine's imperative surface |
| `glimmer-motion/presence`, `/layout-group`, `/motion-config`, `/reorder/group`, `/reorder/item` | The same components by their own entry points |
| `@cardstack/choreo` | `<Choreo>`, `beacon`, `at` / `after`, `createArming`, and the `Sprite` / `Changeset` types |
| `@cardstack/choreo/film` | Film (scored, seekable sequences) |
| `glimmer-motion/test-support`, `@cardstack/choreo/test-support` | Test helpers for `.test.gts` files ([references/testing.md](references/testing.md)) |
**motion-dom is reached only through glimmer-motion.** `motion-dom`, `motion` and `framer-motion` do not resolve in a realm. glimmer-motion re-exports the imperative subset a card needs — `motionValue` (and the `MotionValue` type), `animate`, `transformValue`, `styleEffect`, `frame` — and those are the engine's own functions, sharing the frame loop `{{motion}}` runs on. Do not pull a second copy of Motion from an ESM CDN: it would run its own frame loop and know nothing about the host's layout animations.
## Pick the smallest pattern that states the intent
Escalation order: element → presence → layout → Choreo.
| The ask sounds like | Pattern | Read |
| --- | --- | --- |
| "fade/slide/scale this in", hover/tap states, keyframes, variants, stagger | `{{motion}}` with `initial` / `animate` / `transition` | [element.md](references/element.md) |
| "animate it when it's removed", list add/remove, a panel opening and closing | `<Presence>` + `exit` | [presence.md](references/presence.md) |
| "it moved because the layout changed", a filtered grid, a tab indicator, a thumbnail opening into a detail view of the SAME thing | `layout=true` / `layoutId` / `<LayoutGroup>` | [layout.md](references/layout.md) |
| drag, swipe-to-dismiss, a reorderable list or grid | `drag` / `<ReorderGroup>` | [drag-and-reorder.md](references/drag-and-reorder.md) |
| parallax, a scroll progress bar, reveal-on-scroll | `scrollProgress` / `InView` / `whileInView` | [scroll.md](references/scroll.md) |
| "first X, THEN everyone moves, THEN Y"; z-index for the span of a move; one element's motion computed from another's box; flying to a place that must not deform; two views of the card swapping as one Magic Move | `<Choreo>` timeline (+ `{{beacon}}`) | [choreo.md](references/choreo.md) |
| a deliberate snapshot morph of part of the card | `viewTransition(update, element)` | [view-transitions.md](references/view-transitions.md) |
The classic wrong reaches:
- **A view transition for live content.** `startViewTransition` animates bitmaps, so anything running inside — a demo, a video, a canvas — freezes for the crossfade, and the document-wide form snapshots the host's whole page. `layout=true` moves the real elements.
- **`layoutId` to fly an item into a trash can.** `layoutId` morphs one element into another; the bin would stretch into a row. A destination that is a _place_ is a `{{beacon}}` and `<c.Move @to>`.
- **`setTimeout` to sequence animations.** That is what `<Choreo>`'s `c.Sequence` replaces: its "after" comes from real durations, including a spring's settle time.
- **`<Choreo>` for one element.** One element, no ordering, no cross-element measurement: `{{motion}}` (or `<Presence>` if it leaves).
- **A one-off CSS entrance is fine as CSS.** A single keyframed fade needs no library; follow the resting-state rule in `boxel-ui-guidelines/references/template-patterns.md` (the resting CSS state is the final one). Reach for glimmer-motion when the motion depends on state, interrupts, leaves the DOM, or follows layout.
## The three Glimmer rules (each silently stops motion)
1. **Motion owns the inline style.** Never put a bound `style="…"` attribute on a motion element: Glimmer rewrites the whole declaration on re-render and wipes the transform the engine just wrote. Pass styles through the modifier instead.
```gts
{{! ✗ }} <div style={{this.accent}} {{motion drag=true}} />
{{! ✓ }} <div {{motion style=(styles background=this.accent) drag=true}} />
```
(Static styling belongs in `<style scoped>` as always; this is about values you bind.)
2. **Declare what should be tweened or corrected.** A stylesheet `border-radius` is invisible to the engine, so a layout-animating tile grows with oval corners. Pass radius and shadow through the modifier: `{{motion layout=true style=(styles borderRadius='14px')}}`.
3. **A leaving element stays live.** Glimmer re-runs a leaver's block from current tracked state while its exit plays, so whatever the exit shows must ride on the item `<Presence>` yields, not be re-read from state that has already moved on.
## Cards share the host's copy
Every card on the page and the host's own UI run on one instance of each library, so their module-global state is shared: the beacon registry, Choreo's region registry, far matching, the layout scheduler and the global motion speed. The same card can also render twice at once (in two stacks, or isolated in one and embedded in another). So:
- **Scope every name a card registers by the card's id.** Beacon names are document-wide and the first registration wins; a `<Choreo @id>` is looked up host-wide; an id that leaves one `<Choreo>` region and appears in another in the same render pass far-matches and flies between them; `layoutId`s pair across the page unless a `<LayoutGroup @id>` namespaces them. Build them with `concat` from `@ember/helper` (`(concat @model.id '-trash')`), or wrap a card's `layoutId`s in `<LayoutGroup @id={{@model.id}}>`. Leave `<Choreo @id>` off unless something addresses the region.
- **Do not change global tempo.** `setMotionSpeed` slows every animation in the host. A card that wants slow motion for a demo scales its own transitions.
- **Animate inside the card's own box.** The host owns the stack, the card container and the format chrome around your template. Put `<Choreo>` around the part of the card that is the scene — the list, the panel — never try to choreograph outside the template.
- **A card scrolls in its stack item, not the window.** Scroll-linked motion names its scroller explicitly ([scroll.md](references/scroll.md)).
- **Tracked state lives on a top-level component.** Motion is driven by tracked state, and `boxel parse` rejects decorators inside a `static isolated = class {…}` expression. Declare the view as its own class and assign it: `class InboxView extends Component<typeof Inbox> { @tracked open = false; … }`, then `static isolated = InboxView;`.
- **Reduced motion is respected by default.** `<MotionConfig @reducedMotion>` defaults to `"user"`: under `prefers-reduced-motion`, transform and layout animation are off while opacity and colour still animate. Don't override it to make a demo "work".
- **Fitted and embedded formats render many instances.** Keep per-instance motion cheap (opacity and transform) and let the card that owns a list choreograph it, not each item.
## References
- [references/element.md](references/element.md) — `{{motion}}`: targets, transitions, keyframes, variants, gestures, motion values.
- [references/presence.md](references/presence.md) — `<Presence>`: exits, modes, the single-conditional-element form.
- [references/layout.md](references/layout.md) — `layout`, `layoutId`, `<LayoutGroup>`.
- [references/drag-and-reorder.md](references/drag-and-reorder.md) — `drag`, drag controls, `<ReorderGroup>` / `<ReorderItem>`, touch rules.
- [references/scroll.md](references/scroll.md) — `scrollProgress`, `InView`, `whileInView`.
- [references/choreo.md](references/choreo.md) — `<Choreo>` scenes, steps and selectors, beacons, nested regions and far matching.
- [references/view-transitions.md](references/view-transitions.md) — `viewTransition` scoped to the card, and when not to.
- [references/testing.md](references/testing.md) — testing animated cards under `boxel test`.From cardstack/boxel-skills, MIT.
More from cardstack/boxel-skills
- 0.592score
boxel
cardstack
Use whenever creating, reading, or editing Boxel cards (.gts files), card instances (.json), fields, templates, queries, or anything in a Boxel realm.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-markdown-format
cardstack
Use when authoring a `markdown` template (static markdown format) on a CardDef or FieldDef — defaults, markdownEscape, and markdown helpers.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-patterns
cardstack
Use when the user names an outcome ("show a chart", "let users pick a color", "build a dashboard", "summarize comments", "embed AI image generation", "lay out…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-theme-development
cardstack
Use when the deliverable is a theme ARTIFACT — creating, converting, auditing, or patching Theme, StructuredTheme, StyleReference, DetailedStyleReference, or…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-ui-component-discovery
cardstack
MANDATORY before writing any UI in a `.gts` template, including a quick fix to an existing card (turning a styled span or div into a button, wiring a dead…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-ui-guidelines
cardstack
Use when IMPLEMENTING or REVIEWING UI in Boxel templates (writing a template, or reviewing a change, diff or pull request that touches one) — applying…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
catalog-listing
cardstack
Use when installing, browsing, remixing, updating, or submitting catalog listings (Apps, Cards, Fields, Skills, Themes) from a Boxel catalog realm.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
catalog-reuse
cardstack
MANDATORY before writing any `.gts`.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-design
cardstack
Use when DECIDING a Boxel card's visual language — mood, palette, typography direction, asset direction, one visual signature, the design-playbook process.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-environment
cardstack
Use when running, navigating, or orchestrating tasks inside the live Boxel application — switching between Code Mode and Interact Mode, searching and editing…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-file-def
cardstack
Use when adding or working with file-typed fields (FileDef, ImageDef, MarkdownDef, PngDef, CsvFileDef).
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-flavored-markdown
cardstack
Use when authoring or editing Boxel Flavored Markdown (BFM) content — content fields rendered as rich markdown with :card/::card directives, mermaid diagrams…
SkillAFreshness: A★ 1Claude Code +9
Signals
- Stars
- 1
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Oct 16, 2026 (12 days ago)
- Last release
- Oct 23, 2026 (5 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/cardstack/boxel-skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from cardstack
- 0.592score
boxel
cardstack
Use whenever creating, reading, or editing Boxel cards (.gts files), card instances (.json), fields, templates, queries, or anything in a Boxel realm.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-design
cardstack
Use when DECIDING a Boxel card's visual language — mood, palette, typography direction, asset direction, one visual signature, the design-playbook process.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-environment
cardstack
Use when running, navigating, or orchestrating tasks inside the live Boxel application — switching between Code Mode and Interact Mode, searching and editing…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-file-def
cardstack
Use when adding or working with file-typed fields (FileDef, ImageDef, MarkdownDef, PngDef, CsvFileDef).
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-flavored-markdown
cardstack
Use when authoring or editing Boxel Flavored Markdown (BFM) content — content fields rendered as rich markdown with :card/::card directives, mermaid diagrams…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
boxel-markdown-format
cardstack
Use when authoring a `markdown` template (static markdown format) on a CardDef or FieldDef — defaults, markdownEscape, and markdown helpers.
SkillAFreshness: A★ 1Claude Code +9
Cite this page
card-motion skill. Agent Mart. https://agentmart.dev/skills/cardstack-card-motion (last updated 2026-10-24)