Design System

Motion

Motion that means something, with no bounce and no spring.

Motion is functional. Every animation either signals a state change, draws the operator’s eye to something new, or indicates that the system is live. Motion is never decorative - there are no flourishes, no overshoots, no reveals for their own sake.

Tempo

Different categories of change earn different durations. The scale is tight on purpose - fast enough that an operator doesn’t wait, slow enough that the change registers.

Change class Duration Examples
UI state change 150–250ms button hover, toggle flip, focus ring, tab switch
Panel entrance / exit 400–600ms drawer open, sheet appear, modal in, banner dismiss
Ambient signal 1–2s radar sweep rotation, live pulse, sonar ping

Easing

Two curves cover the system.

  • UI motion uses cubic-bezier(0.2, 0.8, 0.2, 1) - fast out, gentle settle. Applies to everything in the 150–600ms range.
  • Tactical simulations use linear easing. Radar sweeps, clock ticks, countdown bars - these represent physical-world processes that don’t ease in and out. Linear is the honest choice.

Signature motions

Four motions appear often enough across the system to earn their own names. Learn them; reuse them; don’t invent new ones without a design review.

Name Duration Behavior
Acquire 200ms, ease-out Electric-blue brackets [ ] snap inward around a target. --fdt-glow-md blooms at the end of the snap and settles to --fdt-glow-sm over the following 300ms. Used when a track is locked, a unit is selected, or a decision is committed.
Sweep 2s, linear, loop Radar sweep in electric-500 rotates continuously. A 30° trail follows at 30% opacity, peaking at --fdt-glow-md. The trail never fully clears - the sweep is the system telling the operator it’s awake.
Panel slide 350ms, ease-out Translucent panel translates in from the viewport edge while fading in. Exit reverses. No overshoot. Drawers, sheets, and mobile HUD collapses all use this.
Live pulse 1.2s, sinusoidal Opacity-only pulse on --fdt-glow-sm. Never touches scale or translate. Applied to elements actively receiving data - contacts refreshing, incoming feeds, live telemetry.

Hard rules

  • No bounce, no overshoot, no spring physics. The system is not playful. Elements arrive at their target position and stop.
  • Opacity is the default channel for “live” signals. Scale and translate are reserved for state changes, not for signalling activity.
  • Motion respects prefers-reduced-motion: reduce. See Accessibility for the full fallback behavior - radar sweep freezes, live pulse holds at 100%, panel slides become 150ms crossfades.