Visual Identity

Motion & Dark Mode

Motion in Playbook is fast, purposeful, and never in the way — and the same discipline carries into dark mode, where color is remapped intentionally rather than simply inverted.

Animation here is a tool, not decoration. Every motion in the system has to earn its place against four principles, and if it fails any one of them, it gets removed. The thread running through all of it is restraint: short durations, consistent easing, and an absolute respect for players who’ve asked their device to calm motion down.

Purposeful

Every animation communicates a state change, guides attention, or gives feedback.

Test Can you explain why it animates? If not, make it instant.

Fast

Users never wait for an animation to finish before they can act.

Test Does it block interaction? If yes, shorten or remove it.

Accessible

Animations respect the reduced-motion setting, and no content hides behind motion.

Test Does the page work identically with all motion off?

Consistent

The same interaction produces the same motion everywhere.

Test Could a user predict it from other parts of the UI?

The duration scale

Timing is a fixed scale, not a per-component guess. Micro-interactions are tight — a hover at 150ms, a panel at the 250ms base — and nothing runs past a second. Anything that needs longer is broken into staggered steps instead.

TokenDurationUse for
xs100msButton press, instant feedback
sm150msHover states, toggles, micro-interactions
md250–300msModals, panels, drawers, tab switches
lg500msPage transitions, complex reveals
xl800msData visualizations, chart entrances
Two timing rules worth memorizing

Micro-interactions above 200ms feel sluggish — keep them tight. And exit animations are always shorter than entrances: exit equals roughly 75% of the entrance duration, so things leave a little quicker than they arrive.

Easing curves

Easing is what gives motion its character, and Playbook never uses the CSS default ease — it’s too generic and feels inconsistent across components. Instead, five named curves map to five intentions: things arriving decelerate, things leaving accelerate, and interactive feedback gets a subtle spring.

ContextCurvecubic-bezierWhen
EntranceEase-out (decelerate)cubic-bezier(0, 0, 0.2, 1)Elements arriving — modals, toasts, page content
ExitEase-in (accelerate)cubic-bezier(0.4, 0, 1, 1)Elements leaving — closing modals, dismissing toasts
InteractiveSpringcubic-bezier(0.34, 1.56, 0.64, 1)Toggles, button press/release, selection pops
Two-wayEase-in-outcubic-bezier(0.4, 0, 0.2, 1)Smooth transitions — tab underlines, slider thumbs
ProgressLinearlinearProgress bars, loading indicators, countdowns

Entrance & exit patterns

Five patterns cover almost everything. Each pairs an entrance with an exit and stays within deliberately small bounds — slides translate no more than 24px, scales stay between 0.95 and 1.05 — so motion reads as polish rather than spectacle.

Fade

Opacity transition — the simplest and most accessible pattern.

Use for Overlays, backdrops, tooltips, popovers, in-place content.

Slide

Small translate (8–24px max) that implies where something comes from.

Use for Side panels, drawers, nav menus, mobile sheets, toasts.

Scale

Transform scale, kept tight to 0.95–1.05 so it never looks cartoonish.

Use for Button press, card hover lift, modal entrance, popovers.

Stagger

50ms between items, capped at 5 — the rest appear instantly.

Use for Card grids, list items, dashboard widgets, quiz options.

For progressive disclosure — accordions, expandable details, FAQ sections — the system animates grid-template-rows from 0fr to 1fr rather than animating height or max-height directly. That keeps the collapse GPU-composited and layout-stable. Component motion follows from these primitives: a card lifts 2px on hover, a modal backdrop fades while its panel scales from 0.95 to 1, and a toast slides in from the right (or from the bottom on mobile).

Loading: skeletons, not spinners

For page-level loading, use skeleton placeholders shaped like the content they replace, with a left-to-right shimmer — never a full-page spinner. Spinners are reserved for small, self-contained actions like a button submission or saving a preference. As content streams in, fade each section as it arrives rather than waiting for everything at once.

The reduced-motion rule

This is the non-negotiable of the entire system. Every Playbook implementation must honor the operating system’s reduced-motion preference — it is not optional and it is not a nice-to-have.

Respect prefers-reduced-motion — always

When a player has asked their device to reduce motion, every transform and transition collapses to near-instant. Slides and scales land in their final position immediately, fades complete in under a millisecond, and content is visible right away. Crucially, nothing is ever hidden or made unreachable because an animation didn’t run — the page works identically with all motion off.

The same accessibility discipline extends beyond that one media query:

  • No content behind animation. Everything must be readable and interactive even if animations never run.
  • No autoplay. Looping animations don’t start without user action — the skeleton shimmer is the only exception, because it’s a loading indicator, not decoration.
  • No flashing. Nothing flashes more than three times per second — a hard WCAG 2.3.1 requirement.
  • No motion-sickness triggers. No parallax scrolling, no zooming transitions, no rotation animations.
  • Pause controls. Any looping element — a carousel, rotating tips — needs a visible pause or stop button, and auto-advancing content must allow enough reading time.
Tier 2 calms the motion down

On support, self-exclusion, and helpline pages, the motion language softens: spring easing is replaced with ease-in-out, slides become plain fades, scale effects disappear, and durations stretch a little. No confetti, bounces, or pops — and helpline numbers appear immediately, never behind a stagger. This mirrors the warmer register in Voice & Tone.

Dark mode

Dark mode isn’t an inverted light mode — it requires intentional color mapping to keep readability, hierarchy, and brand identity intact. The default behavior is to auto-switch on the system’s dark preference and to persist an explicit in-app toggle. The one firm rule: never force dark mode, and always respect the system preference unless the user has chosen otherwise in the app.

Semantic color mapping

Each token has a deliberate dark-mode value, and every pairing is verified against WCAG 2.1 AA contrast on the dark background. Notably, links and the secondary CTA shift to the brighter teal on dark, while accents move to the lighter orange.

TokenLight modeDark modeRatio on dark
Backgroundneutral-50 #F5F5FAneutral-900 #1A1A2E
Surfacewhite #FFFFFFneutral-700 #3D3D5C
Text primaryneutral-900 #1A1A2Eneutral-50 #F5F5FA15.70:1
Text secondaryneutral-700 #3D3D5Cneutral-300 #A8A8C07.33:1
Linknavy #2A3F56teal #00D4AA8.93:1
Accent (CTA)orange #FF6B35orange-light #FF8A5C7.34:1
Status colors keep dark text — in both modes

Success, warning, danger, and info always use dark text on their chromatic backgrounds, in light and dark mode — never white text on those colors. Muted text (neutral-500) is the one trap in dark mode: at 3.33:1 it passes for large text only, so use it sparingly and only at 18px+ or 14px+ bold.

Image & media treatment

Imagery needs its own adjustments so nothing glares or bleeds on a dark surface. The most important is dimming photographs slightly; SVG logos and the brand gradient bar need no change.

Asset typeDark-mode treatment
PhotographsReduce brightness to 85–90% to prevent glare on dark backgrounds.
Illustrations / iconsUse light-on-dark variants — swap stroke and fill colors.
Charts / data vizLight text and gridlines; reduce opacity of non-essential elements.
ScreenshotsAdd a subtle 1px border so edges don’t bleed into the background.
Brand gradient barNo change — the orange-to-teal gradient works on both light and dark.
Tier 2 stays in light mode

Support pages always render in light mode regardless of the system setting — dark mode can feel isolating in a crisis context. When the theme does change, the transition itself is gentle: a 150ms ease-out fade on background and text color, which is exactly the kind of purposeful, fast motion the rest of this page describes.

Motion and dark mode are the finishing layer of the design system. Both report to the brand book’s visual integration test — place the work beside the operator’s commercial content and ask whether it belongs. For the tokens these rules build on, see Color, and for the stroke language the animated charts inherit, see Iconography.

Source in the Playbook repo: visual-identity/motion/ , brand-book/03-visual-identity.md