Recipes

Short patterns for common UI, each one taken from the demo that ships with the package. Toasts, modals, tabs and screen swaps are on the transitions page, and lists on the stagger page.

Hover, press and focus Pro

playButton.OnHover().ScaleTo(1.08f, 0.12f, Ease.OutBack);
playButton.OnPress().ScaleTo(0.94f, 0.08f);
playButton.OnFocus().ScaleTo(1.08f, 0.15f, Ease.OutBack);   // keyboard and gamepad get the same feedback

Declare these once when you set up the screen, not inside event handlers. Pair OnHover with OnFocus, or the feedback only works with a mouse.

Accordion

void ToggleAccordion()
{
    open = !open;
    body.Animate().Height(open ? 168f : 0f, 0.3f).Ease(Ease.OutCubic);
}

Give the body overflow: hidden in USS so its contents are clipped while it closes. Height re-runs layout every frame, which is what an accordion needs; for many elements at once, prefer MoveX, ScaleTo and Rotate, which don't.

Named states Pro

card.Variants()
    .State("normal",   s => s.ScaleTo(1f).RotateTo(0f).FadeTo(1f).In(0.35f).WithSpring(SpringPreset.Snappy))
    .State("featured", s => s.ScaleTo(1.2f).RotateTo(-5f).FadeTo(1f).In(0.35f).WithSpring(SpringPreset.Bouncy))
    .State("dim",      s => s.ScaleTo(0.9f).RotateTo(0f).FadeTo(0.4f).In(0.3f).With(Ease.OutCubic));

card.To("featured");   // later, from anywhere

Declare each state once and move between them by name. Selection, difficulty pickers and inventory slots fit this well: three states cost three declarations, not a transition for every pair.

A sequence with async/await

async void PlayIntro()
{
    bool finished = await title.Animate().Fade(1f, 0.4f).From(0f).Ease(Ease.OutCubic);
    if (!finished) return;   // cancelled: the screen closed, so stop here
    await subtitle.Animate().MoveY(0f, 0.35f).From(20f).Ease(Ease.OutCubic);
    await startButton.Animate().ScaleTo(1f, 0.3f).From(0.8f).Ease(Ease.OutBack);
}

Always check the result. An intro that continues after its screen has closed is a common source of errors. Await each animation once; keep the result if you need it again.

Without async, Then() does the same and allocates nothing:

card.Animate()
    .MoveY(-40f, 0.3f).Ease(Ease.OutCubic)
    .Then().MoveY(0f, 0.5f).Delay(0.6f).Ease(Ease.OutBounce);   // rise, hold 0.6 s, fall

Loops

var pulse = badge.Animate().ScaleTo(1.15f, 0.5f).Ease(Ease.InOutSine).Loop(LoopMode.PingPong, 0);  // 0 = forever
spinner.Animate().Rotate(360f, 1f).Loop(LoopMode.Restart, 0);

Keep the handle of a loop that runs forever. Without it, the only way to stop it is StopAnimations() on the element.

Bump something that is already moving

ship.Animate().MoveX(400f, 2f);           // a long move
ship.Animate().NudgeY(-12f, 0.15f);       // a hit: adds a bump without stopping the move

MoveX on an element that is already moving replaces that movement. Nudge, NudgeX and NudgeY add on top of it instead, which is what screen shake and hit reactions need.

Count a number up

int from = shown, to = coins;
scoreLabel.Animate().Value(0f, 1f, 0.6f, t => scoreLabel.text = Mathf.RoundToInt(Mathf.Lerp(from, to, t)).ToString())
          .Ease(Ease.OutCubic);

Respect reduced motion

MotionSettings.Mode = MotionMode.Reduced;   // Full, Reduced, Crossfade or None

Set it once from your accessibility settings. Every animation started afterwards follows it: Reduced shortens and calms motion, Crossfade replaces movement with fades, and None jumps to the end values. Callbacks and await still complete, so game logic waiting on an animation keeps working.

For motion that carries meaning, such as a loading spinner, opt out:

spinner.Animate().Rotate(360f, 1f).Loop(LoopMode.Restart, 0).IgnoreReducedMotion();

Common mistakes

What you seeWhyFix
The fade does nothingThe element is already at the target valueAdd From(0f)
It animates but stays invisibleA previous Hide() left it at display: noneUse Show(), not AnimateIn()
layout.x or layout.width is 0Read before the first layout passRead it in a GeometryChangedEvent callback
OnComplete never runsThe animation was cancelled or replaced, not finishedUse OnSettled, which runs either way
A bump stops the movementMoveX replaces the running moveUse NudgeX
The animation stops when a screen closesThe element left the panelIntended: Cascade cancels it so nothing writes to a closed screen
A staggered list feels slowThe step is too large0.04–0.08 s between items