04. Motion.

Chapter 04·Organic, not mechanical
Our motion language is biological. Things breathe, radiate, shimmer, drift. Nothing slides. Nothing bounces. Nothing snaps. The logo sets the tempo at 2.8 seconds — everything else follows.

Seven primitives.

The complete motion vocabulary. Every animation in the system is built from these seven — used alone, stacked, or staggered. Their names are the public API; use them in code exactly as written.

Concentric rings expanding outward and fading. The core signature of the brand — everywhere we need "presence," we radiate.

lmx-radiate3000ms · infinite

Gentle opacity breath on a directional gradient. Used on the six logo beams, staggered by 0.3s each — makes the mark feel alive without spinning.

lmx-beam2800ms · infinite

Radius breath on the core circle. 9→11→9. Subtle. The logo's heartbeat. Never animate other shapes with this — it's specific to the core.

lmx-core2800ms · infinite

Scale + opacity on a radial gradient. Creates the "atmosphere" around the hero mark. Use for ambient backgrounds on heroes and section openers.

lmx-atmosphere4000ms · infinite
genuinely

Slow linear gradient drift across text. Reserved for one phrase per page — the verb that carries the thesis. Eight full seconds; any faster and it reads as glitter.

lmx-shimmer8000ms · infinite

A single light traveling along a beam, then gone. Triggered on page load and on major interactions. It says "information just arrived."

lmx-spark2800ms · infinite

General-purpose breath — scale 1 → 1.02, opacity 0.85 → 1. Apply to passive cards or badges when you want presence without movement.

lmx-breathe3000ms · infinite

Tempo & easing.

Everything is tuned to the 2.8-second breath. That's the logo's core pulse. Our easings are organic — they start gentle, stay gentle, settle gentle. No snap, no overshoot, no rubber band.

Durations

--dur-breath
2800ms
--dur-radiate
3000ms
--dur-atmosphere
4000ms
--dur-shimmer
8000ms

Instant transitions (hover, focus) are 150–300ms. Anything longer belongs to the breath family.

Easings

--ease-organic
(.4, 0, .2, 1)
--ease-emerge
(0, 0, .2, 1)
--ease-settle
(.4, 0, .6, 1)

Forbidden: cubic-bezier(.68,-.55,.27,1.55) and every other rubber-band curve. We don't overshoot.

Code you can steal.

Drop this into any product. It matches the home mark's rhythm exactly. All primitives are already defined in base.css — you just have to apply them.

@keyframes lmx-radiate {
  0%   { transform: scale(1);   opacity: .7; }
  40%  { border-color: rgba(198,228,255,.35); }
  100% { transform: scale(2.8); opacity: 0;  }
}

.ring {
  position: absolute;
  border-radius: 50%;
  border: 1.5px solid rgba(245,200,66,.55);
  width: 40px; height: 40px;
  animation: lmx-radiate var(--dur-radiate) var(--ease-organic) infinite;
}
.ring:nth-child(2) { animation-delay: 1s; }
.ring:nth-child(3) { animation-delay: 2s; }

Never this.

The easy wins of generic motion design are the exact things that make products feel like everyone else. If something you're building uses any of these, stop and ask what the brand would do instead.

— Forbidden

  • Slide-in on scroll. We do not move content to get attention.
  • Bounce / rubber-band easings. Overshoot is a different brand.
  • Fade-up on page load. Elements appear where they belong.
  • Spinning loaders. Use a breathing mark or a progressive beam.
  • Parallax. We are not a 2014 Apple product page.
  • Hover-tilt 3D card effects. Keep surfaces flat; use glow.
  • Staggered list entrances. Lists are lists.

— Preferred

  • Breathing loops on key elements. Let them be alive, not arriving.
  • Opacity + color transitions on hover, 200ms, organic ease.
  • Soft glow on primary buttons as they receive intent.
  • A single shimmer on the verb that carries the thesis.
  • Staggered beam pulses — never staggered content.
  • Atmospheric radial gradients drifting under hero content.
  • When you need "loading," use the radiating ring. Always.

Reduced motion.

When the user's OS says so, we stop. Completely. The base stylesheet already honors prefers-reduced-motion — all animation durations collapse to 10ms and iteration count to 1. Design for this state: the page must still feel right.

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}