Brand · Motion library

v1.1 · Locked

Motion library

The brand mark stays in position. The geometry / colours reconstruct.

Nine animation variants — four entrance one-shots, five ambient loops. Each runs in code (Framer Motion + SVG). No gifs. Every variant retargets the locked Habañero palette. This page is the canonical reference for every animation that ships.

The mark in motion

At rest, then animating as Pulse — the visual definition of spanda.

Static

The mark at rest. Six lexicon petals + soft bindu. Used in logos, favicons, every brand application.

Pulse · staggered breath

Each petal scales 1.0→1.06 with an 80 ms stagger. Rhythm radiates outward from the bindu.

Nine variants

Four entrance one-shots, five ambient loops. Each demo includes the recommended use-case.

One-shot
bloom-in

Bloom

Petals grow from the bindu outward, staggered. The signature entrance — the visual definition of expandere.

Use for

Page load · Modal entrance · Agent activation

One-shot
scatter

Scatter

Petals fly in from far away, each from the direction it points. They settle into place with a spring overshoot.

Use for

Hero-section reveal · Dramatic load states

One-shot
cascade

Cascade

Petals appear one at a time, clockwise, each rotating 120° as it scales in. Bindu appears last.

Use for

Storytelling moments · Guided onboarding

One-shot
spiral

Spiral

Petals rotate a full 360° while scaling from zero. Most dramatic of the entrances.

Use for

Major brand moments · Splash screens

Looping
pulse

Pulse

Continuous gentle breathing. Each petal scales 1.0→1.06 with a stagger, creating a wave that travels around the bloom.

Use for

Ambient dashboard presence · Background agent activity

Looping
heartbeat

Heartbeat

A real cardiac rhythm — quick double-pulse, then a long resting phase. Bindu pulses harder than petals.

Use for

Live data states · Monitoring widgets · Real-time activity

Looping
inhale

Inhale / Exhale

Full breath cycle. Petals contract toward the bindu, the bindu inflates, then everything expands back with overshoot.

Use for

Hero / meditation states · Focus mode · Brand storytelling

Looping
sweep

Sweep

A light wave travels clockwise around the bloom. Each petal brightens and scales as the wave passes through it.

Use for

Loading / processing states · Long-running operations

Looping
swap

Palette swap

Same geometry, palette cycles every 2.4 s through Habañero → Strawberry → Aurora → Warm Earth.

Use for

Hero / loading-screen identity moments

Duration tokens

Four tokens. Use the smallest one that gets the job done.

TokenValueUse for
fast120msHover states, focus rings, button presses. Imperceptible response.
base200msDefault transition. Component state changes, dropdowns, tooltips.
slow320msModal opens, page panels, list reorders. Felt as deliberate.
deliberate480msHero animations, marketing reveals, large layout shifts.

Easing curves

Three curves. Most things use standard. Spring for delight. Decelerate for entrances.

Standard

The default. Quick start, soft settle. Use for nearly every state change.

cubic-bezier(0.16, 1, 0.3, 1)

Spring

Slight overshoot. Use sparingly — tap feedback, success confirmations, agent appearances.

cubic-bezier(0.34, 1.56, 0.64, 1)

Decelerate

Linear-out. For things entering the viewport — modals, drawers, toasts.

cubic-bezier(0, 0, 0.2, 1)

The library stack

What ships motion in production. None of this is gifs — every animation is code, every animation is controllable.

Framer Motion

Primary · installed

Component-level motion: enter / exit, gestures, layout shifts, presence, modals. Powers all bloom variants. The 80% library.

www.framer.com/motion
npm install framer-motion
import { motion } from "framer-motion";

<motion.div
  initial={{ opacity: 0, y: 8 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }}
>
  Beat just rescheduled three tasks.
</motion.div>

GSAP + ScrollTrigger

Add when marketing site ships

Scroll-driven choreography. The Sarvam / Monday hero sequences. Outside React paradigm — imperative, but unmatched for timeline control.

gsap.com
npm install gsap
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";

gsap.to(".hero", {
  scrollTrigger: { trigger: ".hero", scrub: 1 },
  y: -100, opacity: 0,
});

Lottie React

Add when commissioning illustration

Hand-crafted illustration animations from After Effects → Bodymovin → JSON. Vector-based, scalable, tiny.

airbnb.io/lottie/
npm install lottie-react
import Lottie from "lottie-react";
import beatAgent from "./agents/beat.json";

<Lottie animationData={beatAgent} loop autoplay />

CSS / Tailwind

Already in use

Hover, focus, simple transitions. The motion you don't notice. Zero library overhead.

tailwindcss.com/docs/transition-property
<button
  className="bg-beat-500 hover:bg-beat-600
             transition-colors duration-base
             ease-standard"
>
  Run agent
</button>

Skipped intentionally: Rive (interactive vector — not needed yet), Three.js / WebGL (3D — overkill), tailwindcss-animate (too generic, doesn't match brand).

Motion principles

Five rules that govern every animation in Espanda.

01

Motion has a meaning.

Every animation is named after a lexicon word or a real concept (heartbeat, inhale, sweep). If a motion doesn't fit one of the canonical variants, we don't ship it.

02

Smaller is better.

Pick the smallest duration that gets the message across. 120 ms covers most state changes. Reach for 480 ms only on hero / marketing reveals.

03

Standard ease wins.

Use spring sparingly — only when you want the user to notice. Most motion should feel inevitable, not performative.

04

Ambient motion is rhythm.

Pulse and Hum loop continuously on dashboards and agent surfaces. They make the product feel alive without demanding attention. ~1.5 s for Pulse — slow heart rate, not dance music.

05

Respect reduced-motion.

Honour prefers-reduced-motion. All ambient loops disabled, all transitions reduced to opacity-only. Implementation due in component refinement.

Iconography

Two families, two roles.

Phosphor Icons

Brand · installed

Character icons. Six weight variants per icon (thin / light / regular / bold / fill / duotone). The duotone variant is the hero — each lexicon agent gets a duotone Phosphor icon coloured in its lexicon hue.

phosphoricons.com
npm install @phosphor-icons/react
<HeartbeatIcon
  size={24}
  weight="duotone"
  color="#FF5C8D"
/>

Lucide

Plumbing · installed

Utility icons where character isn't needed — Close, Chevron, Check, Copy, Settings, Search. Clean, neutral, comprehensive.

lucide.dev
<X size={20} />
<ChevronRight size={16} />
<Check size={14} />

Lexicon → Phosphor icon mapping for component work: Beat → Heartbeat · Pulse → ActivitySquare · Wave → WaveSine · Spark → Lightning · Hum → CircleNotch · Echo → ArrowsClockwise · Surge → TrendUp · Drift → CompassTool. All in duotone weight.

Install the motion stack

npm install framer-motion @phosphor-icons/react

Both are already in package.json. GSAP comes in when the marketing site ships. Lottie comes in when illustration work begins.