Case Study · BetMGM

Rolling the Odds

Motion design as a measurable UX bet.

Role:Product DeveloperType:A/B ExperimentStatus:Live on production
ArsenalvsChelsea
Live
Home
2.10
Draw
3.40
Away
2.85
01

The Problem

Live betting is a race against your own attention. Odds shift constantly, across dozens of markets, while the user is already parsing scorelines, timers, and their own bet slip. The interface asks people to notice small numeric changes inside a screen that never stops moving.

That collides with a real perceptual limit: change blindness. When several things update at once, the human visual system routinely fails to register that a specific value moved — especially a two-digit decimal buried in a list. A missed odds change isn't a cosmetic issue; it's a decision made on stale information.

The industry's answer has been a green/red flash on update. It works, until everything flashes — then the signal drowns in its own noise and users tune it out. So the question I set out to answer was deliberately narrow.

Can a better motion cue reduce missed odds changes?
02

The Bet I Made

The temptation with a problem like this is to redesign the whole live-odds surface. I did the opposite: the smallest change that could actually be tested. One micro-interaction, one measurable hypothesis, everything else held constant.

The mechanism is a direction-aware roll. When a value changes, the old number rolls out and the new one rolls in — upward when odds lengthen, downward when they shorten — so motion itself encodes direction before you've read a single digit. Color rides along only during the movement, then settles. Pre-attentive motion detection does the heavy lifting; color is confirmation, not the main channel.

It shipped behind a feature flag as a true A/B experiment. If the data doesn't support it, rollback is a config change, not a redeploy.

Start small, measure, expand.
03

Engineering Decisions

Four decisions did most of the work. None of them were about the animation looking nice — they were about shipping it without breaking a production betting surface.

01

Chose a real library on purpose

I could have hand-rolled this in CSS. I reached for an established animation library instead — partly for robustness, but mostly as a due-diligence exercise: understanding its footprint, its escape hatches, and its failure modes before committing a dependency to a high-traffic path.

npm i <lib> → read the source before the docs
02

Didn't reuse the closest component

There was already a per-digit odometer component that looked like a fit. It wasn't. Per-digit rolling produces subtle, wrong-looking motion when a whole value jumps (2.10 → 3.40). I built a per-change roller instead — the unit of animation is the value, not the glyph.

per-digit ✗ per-change ✓
03

The library couldn't do what it looked like it should

The clean path — animating a CSS variable and letting the number interpolate — quietly didn't work: the library tweened the transform but not the value behind it. I split responsibilities: the library owns the Y-transform roll, plain state owns the number and the color class.

transform → library · value + color → React state
04

Found the feature was invisible where it mattered

It animated perfectly in the sandbox and did nothing on real live pages. Those render through a different shared component with its own update path. The fix was tracing that path and wiring the roll into the component that production actually renders — the least glamorous, most important part of the whole thing.

sandbox ✓ → live page ✗ → trace the render path
04

Designing for Truth

A motion tweak is easy to fall in love with, which is exactly why it needs an honest experiment around it. Assignment is random per user. Reduced-motion preferences are respected and bucketed so they can't quietly skew the result. Latency is labeled honestly rather than hidden behind an optimistic spinner.

One correction is worth naming: the initial bundle-size estimate was ~5 KB. The real cost, measured, was closer to 40 KB. I flagged it and re-scoped before it hardened into a commitment — a cheap correction early beats an expensive apology later.

Three metrics, three jobs:

Primary

Engagement

Primary signal — does the cue actually change how users interact with live odds?

Supporting

Reaction time

Supporting signal — do users register and act on changes faster?

Guardrail

Betting behavior

Guardrail — betting patterns and responsible-gaming signals must not move the wrong way.

05

Status & Roadmap

Phase 1 is live in production and the experiment is collecting data. Results will decide whether the motion language expands to the rest of the live experience — and if it doesn't earn its place, the flag comes back off.

  1. Phase 1Current

    Odds animation

    Live A/B on the odds micro-interaction.

  2. 2
    Phase 2

    Bet-slip motion

    Extend the direction-aware language to the slip.

  3. 3
    Phase 3

    Navigation & cards

    System-wide motion, only if the data supports it.

06

Takeaways

01

The smallest testable version is the strongest proposal

A narrow, measurable change is easier to ship, easier to trust, and far easier to defend than a redesign built on taste.

02

Blast radius is a first-class concern

Feature flags, guardrail metrics, and reduced-motion handling aren't polish — they're what let you move fast on a surface where mistakes cost money.

03

Credibility compounds

Correcting the 5 KB → 40 KB estimate out loud bought more trust than a flashy demo ever would. Honest numbers are a feature.