Brand · Motion library
v1.1 · LockedMotion 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.
Bloom
Petals grow from the bindu outward, staggered. The signature entrance — the visual definition of expandere.
Use for
Page load · Modal entrance · Agent activation
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
Cascade
Petals appear one at a time, clockwise, each rotating 120° as it scales in. Bindu appears last.
Use for
Storytelling moments · Guided onboarding
Spiral
Petals rotate a full 360° while scaling from zero. Most dramatic of the entrances.
Use for
Major brand moments · Splash screens
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
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
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
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
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.
| Token | Value | Use for |
|---|---|---|
| fast | 120ms | Hover states, focus rings, button presses. Imperceptible response. |
| base | 200ms | Default transition. Component state changes, dropdowns, tooltips. |
| slow | 320ms | Modal opens, page panels, list reorders. Felt as deliberate. |
| deliberate | 480ms | Hero 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 · installedComponent-level motion: enter / exit, gestures, layout shifts, presence, modals. Powers all bloom variants. The 80% library.
www.framer.com/motionnpm 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 shipsScroll-driven choreography. The Sarvam / Monday hero sequences. Outside React paradigm — imperative, but unmatched for timeline control.
gsap.comnpm 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 illustrationHand-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 useHover, 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.
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.
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.
Standard ease wins.
Use spring sparingly — only when you want the user to notice. Most motion should feel inevitable, not performative.
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.
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 · installedCharacter 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.comnpm install @phosphor-icons/react
<HeartbeatIcon
size={24}
weight="duotone"
color="#FF5C8D"
/>Lucide
Plumbing · installedUtility 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.