The design tool for how your interface behaves

Choreograph hover, press, focus and drag states on a canvas that is a real browser. You design the interaction by doing it.

Open ChoreoRead the docsFree · no account · files stay in your browser

The handoff problem

Designers describe motion in Loom recordings. Engineers reinterpret it by eye. What ships is an approximation of an approximation.

Motion tools think in linear timelines and export artefacts that don’t map to component states or respond to real events. Prototypes show intent and ship nothing.

Code gets it exactly right, and asks designers to think in keyframe syntax to get there. So the interaction is rebuilt by hand after handoff, lossily, every time.

Figma is the source of truth for structure. Choreo is the source of truth for behaviour, so the interaction you hand over is the one that ships.

Scrubbing is the whole idea

Drag a playhead and the component responds in the same frame. No render step, no preview mode. Scroll this section and you are the playhead.

Bank App cardHOVERtransform · opacity
View cards details **7520

Lock your card

What is a virtual card
Your virtual card will have a different number than your physical card. This helps keep your information secure.
Direct deposit
Institution number 832
Transit/branch number 0055
********
Direct deposit details Void cheque
keep scrolling ↓
Playhead0ms
Card · Scale
1.000
Card · Move Y
0.0px
Header · Opacity
1.00

A real template, not a mock-up. In the app this panel follows the playhead you drag; here it follows your scroll. Same keyframes, same numbers.

0ms100ms200ms300ms410ms

You design the interaction by doing it

Nothing to declare up front. Choreo's canvas is a real browser, so the thing you drag is the thing your users will touch.

Bank App card
Live Preview
410ms
View cards details **7520

Lock your card

What is a virtual card
Your virtual card will have a different number than your physical card. This helps keep your information secure.
Direct deposit
Institution number 832
Transit/branch number 0055
********
Direct deposit details Void cheque
hover it · click to change state · flip the switch
HoverPressFocusIn-ViewToggleDragLoad
0ms100ms200ms

This is a real Choreo file, not a picture of one

The Bank App card template, dropped straight into this page. Hover it, click it to flip between its Base and Clicked states, flip the switch. There is no player in between that can drift from what the browser does.

See the canvas docs
New animationesc
Trigger
HoverPressFocusIn-ViewToggleDragLoad
Source element
Pricing cardbutton
Start recording
01

Arm a trigger

Pick one of seven triggers and the element that fires it. That is the whole setup.

Recording Hover · Pricing cardStop
Y −8px
0ms140ms400ms
02

Then just design

Drag it, restyle it, resize it. Every edit lands as a keyframe at the playhead.

Export
  • Vanilla CSSstyles.css
  • Web Animationsanimation.js
  • ReactCard.tsx
  • Motion Specspec.md
Zero dependencies
03

Copy the output

The code panel has been compiling the whole time. Take any of the four targets.

You already know how to animate. You just don't know the syntax.

There is no Animate tab and no property palette. Arm a trigger, make the change you want, and Choreo writes down what you did.

Read the authoring guide

Hover

Enter and exit are edited apart, so a card can rise fast and settle slow instead of playing one curve backwards.

Recorded

  • Move Y0 → −8px240ms
  • Shadowsoft → deep240ms

Every trigger is authored the same way. Arm it, make the change you want, and Choreo writes down what you did.

Seven triggers, each owning its own timeline

A linear timeline is the wrong shape for interface motion. The unit of choreography here is a trigger state, and enter and exit are edited apart, so a card can rise fast and settle slow.

Browse the trigger docs
styles.css
.choreo-bank-app-card {  position: relative;  width: 411px;  height: 530px;  background-image: linear-gradient(0deg, #f7f5f5 0%, #efefef 100%);  box-sizing: border-box;  border: 1px solid #ffffff;  overflow: hidden;  border-radius: 31px;}.choreo-bank-app-card__frame-1686561429 {  position: absolute;  left: 23px;  top: 27px;  width: fit-content;  height: fit-content;  box-sizing: border-box;  display: flex;  gap: 10px;  align-items: center;  transform: translateX(0px) translateY(0px);  opacity: 1;  pointer-events: none;}.choreo-bank-app-card__visa-inc-logo-2005-2014-1 {  width: 30px;  height: 11px;}.choreo-bank-app-card__visa-inc-logo-2005-2014-1 svg {  display: block;  width: 100%;  height: 100%;  overflow: visible;}.choreo-bank-app-card__view-cards-details {  width: 125px;  height: 17px;  color: #171717;  font-size: 14px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__7520 {  width: fit-content;  height: fit-content;  color: #969696;  font-size: 14px;  font-weight: 600;  font-family: 'Inter', sans-serif;  white-space: nowrap;  overflow-wrap: break-word;}.choreo-bank-app-card__card {  appearance: none;  border: none;  margin: 0;  padding: 0;  font: inherit;  text-align: inherit;  background: none;  color: inherit;  position: absolute;  left: 22px;  top: 20px;  width: 367px;  height: 210px;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 72px;  padding: 32px 0px;  justify-content: center;  background-image: radial-gradient(circle, #1b1c23 0%, #32343d 100%);  box-shadow: 0px 11px 34px 0px rgba(0, 0, 0, 0.45);  overflow: hidden;  transform: rotateY(180deg);  border-radius: 12px;  opacity: 0;  cursor: pointer;}.choreo-bank-app-card__frame-1686561438 {  position: relative;  align-self: stretch;  height: 63px;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 10px;  justify-content: flex-end;}.choreo-bank-app-card__frame-1686561432 {  position: relative;  align-self: stretch;  height: 38px;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 10px;  justify-content: center;  background-color: #0000004a;}.choreo-bank-app-card__frame-1686561436 {  position: relative;  align-self: stretch;  height: fit-content;  box-sizing: border-box;  display: flex;  gap: 27px;  padding: 0px 20px;  justify-content: space-between;  opacity: 0.5;}.choreo-bank-app-card__frame-1686561433 {  position: relative;  width: 152px;  height: fit-content;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 10px;}.choreo-bank-app-card__jannet-smith {  width: 152px;  height: 12px;  color: #969696;  font-size: 10px;  font-weight: 600;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__2400-3256-2323-7619 {  width: 152px;  height: 17px;  color: #969696;  font-size: 14px;  font-weight: 600;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__frame-1686561437 {  position: relative;  width: fit-content;  height: fit-content;  box-sizing: border-box;  display: flex;  gap: 27px;  align-items: center;}.choreo-bank-app-card__frame-1686561434 {  position: relative;  width: 67px;  height: fit-content;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 11px;}.choreo-bank-app-card__exp-date {  width: 67px;  height: 17px;  color: #969696;  font-size: 14px;  font-weight: 600;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__05-35 {  width: 67px;  height: 17px;  color: #969696;  font-size: 14px;  font-weight: 600;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__frame-1686561435 {  position: relative;  width: 31px;  height: fit-content;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 11px;}.choreo-bank-app-card__cvc {  width: 31px;  height: 17px;  color: #969696;  font-size: 14px;  font-weight: 600;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__123 {  width: 31px;  height: 17px;  color: #969696;  font-size: 14px;  font-weight: 600;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__card-2 {  appearance: none;  border: none;  margin: 0;  padding: 0;  font: inherit;  text-align: inherit;  background: none;  color: inherit;  position: absolute;  left: 90px;  top: 80px;  width: 227px;  height: fit-content;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 28px;  padding: 12px 16px;  justify-content: flex-end;  align-items: flex-end;  background-image: radial-gradient(circle, #1b1c23 0%, #32343d 100%);  box-shadow: 0px 11px 34px 0px rgba(0, 0, 0, 0.45);  overflow: hidden;  border-radius: 12px;  transform: translateX(0px) translateY(0px) scaleX(1) scaleY(1);  cursor: pointer;}.choreo-bank-app-card__frame-1686561427 {  position: relative;  align-self: stretch;  height: fit-content;  box-sizing: border-box;  display: flex;  gap: 137px;  justify-content: space-between;  align-items: center;}.choreo-bank-app-card__bank {  width: 41px;  height: 17px;  color: #ffffff;  font-size: 14px;  font-weight: 800;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__mynaui-contactless {  width: 18px;  height: 18px;}.choreo-bank-app-card__mynaui-contactless svg {  display: block;  width: 100%;  height: 100%;  overflow: visible;}.choreo-bank-app-card__frame-1686561432-2 {  position: relative;  align-self: stretch;  height: fit-content;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 10px;}.choreo-bank-app-card__uit-sim-card {  width: 27px;  height: 21px;}.choreo-bank-app-card__uit-sim-card svg {  display: block;  width: 100%;  height: 100%;  overflow: visible;}.choreo-bank-app-card__g4158 {  width: 30px;  height: 11px;}.choreo-bank-app-card__g4158 svg {  display: block;  width: 100%;  height: 100%;  overflow: visible;}.choreo-bank-app-card__frame-1686561430 {  position: absolute;  left: 20px;  top: 218px;  width: 367px;  height: fit-content;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 14px;  justify-content: center;  align-items: center;}.choreo-bank-app-card__card-details {  position: relative;  width: 367px;  height: fit-content;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 5px;  align-items: center;}.choreo-bank-app-card__frame-1686561427-2 {  position: relative;  align-self: stretch;  height: 108px;  background-color: #ffffff;  overflow: hidden;  border-radius: 20px;  opacity: 0;  display: none;}.choreo-bank-app-card__frame-1686561422 {  position: absolute;  left: 22px;  top: 18px;  width: 323px;  height: fit-content;  box-sizing: border-box;  display: flex;  gap: 159px;  justify-content: space-between;  align-items: flex-end;}.choreo-bank-app-card__lock-your-card {  margin: 0;  width: 114px;  height: 19px;  color: #979797;  font-size: 16px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__switch {  appearance: none;  border: none;  margin: 0;  padding: 0;  font: inherit;  text-align: inherit;  background: none;  color: inherit;  position: relative;  width: 51px;  height: 24px;  box-sizing: border-box;  display: flex;  gap: 10px;  padding: 0px 2px;  justify-content: flex-end;  align-items: center;  border-radius: 30px;  transform: translateX(0px) translateY(0px);  background-color: #1cc24b;  cursor: pointer;}.choreo-bank-app-card__rectangle-9 {  position: relative;  width: 27px;  height: 20px;  background-color: #ffffff;  transform-origin: 51% 50%;  border-radius: 30px;  transform: translateX(0px) translateY(0px);}.choreo-bank-app-card__frame-1686561423 {  position: absolute;  left: 22px;  top: 71px;  width: 326px;  height: 20px;  box-sizing: border-box;  display: flex;  gap: 115px;  justify-content: space-between;  align-items: center;}.choreo-bank-app-card__what-is-a-virtual-card {  width: 162px;  height: 19px;  color: #979797;  font-size: 16px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__wordpress-external {  position: relative;  width: 20px;  height: 20px;  overflow: hidden;}.choreo-bank-app-card__wordpress-external-2 {  position: absolute;  left: 0px;  top: 0px;  width: 18px;  height: 18px;}.choreo-bank-app-card__wordpress-external-2 svg {  display: block;  width: 100%;  height: 100%;  overflow: visible;}.choreo-bank-app-card__line-19 {  position: absolute;  left: 23px;  top: 53px;  width: 322px;  height: 1px;  fill: none;  stroke: #efefef;  stroke-width: 1px;}.choreo-bank-app-card__line-19 svg {  display: block;  width: 100%;  height: 100%;  overflow: visible;}.choreo-bank-app-card__line-19 svg, .choreo-bank-app-card__line-19 svg * {  stroke: inherit !important;  fill: inherit !important;  stroke-width: inherit !important;}.choreo-bank-app-card__your-virtual-card-will-have-a-different-number-than-your-physical-card-this-helps-keep-your-information-secure {  width: 341px;  height: 30px;  display: none;  color: #b4b4b4;  font-size: 12px;  font-weight: 500;  font-family: 'Inter', sans-serif;  text-align: center;  overflow-wrap: break-word;}.choreo-bank-app-card__group {  position: relative;  align-self: stretch;  height: 278px;  box-sizing: border-box;  display: flex;  flex-direction: column;  gap: 14px;}.choreo-bank-app-card__direct-deposit {  width: 367px;  height: fit-content;  color: #b0afaf;  font-size: 13px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__frame-1686561421 {  position: relative;  align-self: stretch;  height: 163px;  background-color: #ffffff;  overflow: hidden;  border-radius: 20px;}.choreo-bank-app-card__frame-1686561422-2 {  position: absolute;  left: 22px;  top: 18px;  width: 323px;  height: fit-content;  box-sizing: border-box;  display: flex;  gap: 159px;  justify-content: space-between;  align-items: flex-end;}.choreo-bank-app-card__institution-number {  width: 140px;  height: 19px;  color: #b5b5b5;  font-size: 16px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__832 {  width: 21px;  height: 16px;  color: #000000;  font-size: 12px;  font-weight: 500;  font-family: 'Reddit Mono', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__frame-1686561423-2 {  position: absolute;  left: 22px;  top: 71px;  width: 323px;  height: fit-content;  box-sizing: border-box;  display: flex;  gap: 115px;  justify-content: space-between;  align-items: flex-end;}.choreo-bank-app-card__transit-branch-number {  width: 176px;  height: 19px;  color: #b5b5b5;  font-size: 16px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__0055 {  width: 27px;  height: 16px;  color: #000000;  font-size: 12px;  font-weight: 500;  font-family: 'Reddit Mono', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__frame-1686561424 {  position: absolute;  left: 22px;  top: 126px;  width: 323px;  height: fit-content;  box-sizing: border-box;  display: flex;  gap: 133px;  justify-content: space-between;  align-items: flex-end;}.choreo-bank-app-card__account-number {  width: 127px;  height: 19px;  color: #b5b5b5;  font-size: 16px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__node {  width: fit-content;  height: fit-content;  color: #000000;  font-size: 14px;  font-weight: 500;  font-family: 'Reddit Mono', sans-serif;  white-space: nowrap;  overflow-wrap: break-word;}.choreo-bank-app-card__line-19-2 {  position: absolute;  left: 23px;  top: 53px;  width: 322px;  height: 1px;  fill: none;  stroke: #efefef;  stroke-width: 1px;}.choreo-bank-app-card__line-19-2 svg {  display: block;  width: 100%;  height: 100%;  overflow: visible;}.choreo-bank-app-card__line-19-2 svg, .choreo-bank-app-card__line-19-2 svg * {  stroke: inherit !important;  fill: inherit !important;  stroke-width: inherit !important;}.choreo-bank-app-card__line-20 {  position: absolute;  left: 23px;  top: 105px;  width: 322px;  height: 1px;  fill: none;  stroke: #efefef;  stroke-width: 1px;}.choreo-bank-app-card__line-20 svg {  display: block;  width: 100%;  height: 100%;  overflow: visible;}.choreo-bank-app-card__line-20 svg, .choreo-bank-app-card__line-20 svg * {  stroke: inherit !important;  fill: inherit !important;  stroke-width: inherit !important;}.choreo-bank-app-card__frame-1686561428 {  position: relative;  align-self: stretch;  height: 51px;  box-sizing: border-box;  display: flex;  gap: 10px;  padding: 0px 24px;  justify-content: space-between;  align-items: center;  background-color: #ffffff;  overflow: hidden;  border-radius: 20px;}.choreo-bank-app-card__direct-deposit-details {  width: 163px;  height: 19px;  color: #b5b5b5;  font-size: 16px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card__void-cheque {  width: 72px;  height: 15px;  color: #b4b4b4;  font-size: 12px;  font-weight: 500;  font-family: 'Inter', sans-serif;  overflow-wrap: break-word;}.choreo-bank-app-card.is-bank-app-card__card-2-hover .choreo-bank-app-card__frame-1686561429 {  transform: translateX(0px) translateY(16px);  opacity: 0;}.choreo-bank-app-card.is-bank-app-card__card-2-hover .choreo-bank-app-card__card-2 {  transform: translateX(0px) translateY(-28px) scaleX(1.55) scaleY(1.55);}.choreo-bank-app-card__switch.is-bank-app-card__switch-toggle {  transform: translateX(0px) translateY(0px);  background-color: #d8d8d8;}.choreo-bank-app-card__switch.is-bank-app-card__switch-toggle .choreo-bank-app-card__rectangle-9 {  transform: translateX(-19px) translateY(0px);}.choreo-bank-app-card[data-state="clicked"] .choreo-bank-app-card__card {  transform: translateX(-9px) translateY(-9px) rotateY(0deg);  border-radius: 23px;  display: flex;  height: 221px;  opacity: 1;  width: 386px;}.choreo-bank-app-card[data-state="clicked"] .choreo-bank-app-card__card-2 {  transform: translateX(2px) translateY(-23px) rotateY(-180deg) scaleX(1.7) scaleY(1.7);  opacity: 0;}.choreo-bank-app-card[data-state="clicked"] .choreo-bank-app-card__frame-1686561430 {  transform: translateY(132px);}.choreo-bank-app-card[data-state="clicked"] .choreo-bank-app-card__frame-1686561427-2 {  transform: translateX(0px) translateY(0px);  display: block;  height: 106px;  opacity: 1;  width: 370px;}.choreo-bank-app-card[data-state="clicked"] .choreo-bank-app-card__switch {  transform: translateX(0px) translateY(0px);}.choreo-bank-app-card[data-state="clicked"] .choreo-bank-app-card__your-virtual-card-will-have-a-different-number-than-your-physical-card-this-helps-keep-your-information-secure {  display: block;}.choreo-bank-app-card[data-state="clicked"] .choreo-bank-app-card__group {  opacity: 0;}.choreo-bank-app-card[data-state="clicked"] .choreo-bank-app-card__direct-deposit {  transform: translateX(0px) translateY(0px);  opacity: 0.94;}@media (prefers-reduced-motion: no-preference) {  .choreo-bank-app-card__frame-1686561429 {    transition: transform 350ms cubic-bezier(0.25, 1, 0.5, 1), opacity 350ms cubic-bezier(0.25, 1, 0.5, 1);  }  .choreo-bank-app-card__card-2 {    transition: transform 410ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 500ms cubic-bezier(0.33, 1, 0.68, 1);  }  .choreo-bank-app-card__switch {    transition: transform 300ms cubic-bezier(0, 0, 0.58, 1), background-color 300ms cubic-bezier(0, 0, 0.58, 1);  }  .choreo-bank-app-card__rectangle-9 {    transition: transform 300ms cubic-bezier(0, 0, 0.58, 1);  }  .choreo-bank-app-card__card {    transition: transform 500ms cubic-bezier(0.33, 1, 0.68, 1), border-radius 500ms cubic-bezier(0.33, 1, 0.68, 1), height 500ms cubic-bezier(0.33, 1, 0.68, 1), opacity 500ms cubic-bezier(0.33, 1, 0.68, 1), width 500ms cubic-bezier(0.33, 1, 0.68, 1);  }  .choreo-bank-app-card__frame-1686561430 {    transition: transform 500ms cubic-bezier(0.33, 1, 0.68, 1);  }  .choreo-bank-app-card__frame-1686561427-2 {    transition: transform 500ms cubic-bezier(0.33, 1, 0.68, 1), height 500ms cubic-bezier(0.33, 1, 0.68, 1), opacity 500ms cubic-bezier(0.33, 1, 0.68, 1), width 500ms cubic-bezier(0.33, 1, 0.68, 1);  }  .choreo-bank-app-card__group {    transition: opacity 500ms cubic-bezier(0.33, 1, 0.68, 1);  }  .choreo-bank-app-card__direct-deposit {    transition: transform 500ms cubic-bezier(0.33, 1, 0.68, 1), opacity 500ms cubic-bezier(0.33, 1, 0.68, 1);  }  .choreo-bank-app-card__frame-1686561429 {    will-change: opacity, transform;  }  .choreo-bank-app-card__card {    will-change: opacity, transform;  }  .choreo-bank-app-card__card-2 {    will-change: opacity, transform;  }  .choreo-bank-app-card__frame-1686561430 {    will-change: transform;  }  .choreo-bank-app-card__frame-1686561427-2 {    will-change: opacity, transform;  }  .choreo-bank-app-card__switch {    will-change: transform;  }  .choreo-bank-app-card__rectangle-9 {    will-change: transform;  }  .choreo-bank-app-card__group {    will-change: opacity;  }  .choreo-bank-app-card__direct-deposit {    will-change: opacity, transform;  }}

You never wrote it

No syntax, no coefficients, no class names to invent. All of it came from the layers you dragged.

Nothing to install

No Choreo runtime and no required library. Paste it into the project and it runs.

Reduced motion, handled

Every export honours a reduced-motion preference. You did not have to remember.

Or skip it entirely

Send a live link instead, and let the engineer lift these same files from the panel.

Then, at the very end, there's code

You never touched it while designing. These are the actual files Choreo emitted for the card you just used: 56 layers, three triggers and a state machine, in one pass.

See the export options

Not just a timeline. A real editor.

Choreo opens your Figma frames but does not depend on them. Structure, style, states and motion are all editable in-tool.

Why not just use Figma or Lottielab?

Because the three tools are different shapes. Figma owns structure, Lottielab owns illustrative motion, and neither is built to make a hover state behave in a browser.

How Choreo compares with Figma Motion and Lottielab
ChoreoFigma MotionLottielab
Built forInterface micro-interactionsPrototypes and design specsVector and illustrative animation
The canvas isReal DOM, styled with real CSSThe Figma design canvasA vector animation canvas
Time is organised byOne timeline per trigger stateTransitions between framesA single linear timeline
Real UI statesSeven triggers, enter and exit edited separatelyPrototype interactions on framesWhatever the Lottie player exposes
What reaches productionCSS, Web Animations, React, or a written specAn engineer rebuilds it by handA Lottie JSON file
Runtime needed to play itNoneNone; it stays a prototypeThe Lottie player
Handoff isA live link stakeholders can interact withA prototype link plus a written specA file plus the player that runs it

Choreo is not trying to replace either one. It is for the layer in between, where a component has to respond to a real pointer. This comparison reflects how each tool positions itself today; all three keep moving.

Five commitments the tool holds

Each one is a constraint Choreo works within, and together they are the reason you can trust what comes out the other side.

  1. 01

    Predictable, never guessed

    Nothing is generated for you. Every result comes from choreography you performed, so the same file always behaves the same way.

  2. 02

    The canvas is the browser

    Your component is live in the page, so nothing sits between the canvas and what your users see. What you scrub is what ships.

  3. 03

    States, not seconds

    The web is event-driven, so the unit of choreography is a trigger state, not a position on a linear timeline.

  4. 04

    Honest about limits

    When an import cannot be translated faithfully, or something cannot animate smoothly, the tool tells you and points at the layer.

  5. 05

    Deletable

    What you hand off needs no Choreo runtime and no account. Drop the tool tomorrow and nothing it produced breaks.

Your next interaction starts here

Open a file, arm a hover, and drag something. Nothing to install, and nothing leaves your browser.

Free to use · no account · files stay local