RIVE PRODUCTION SPEC
Documentation for Vitto
Vitto Rive Production Specification
Complete Guide for Building the .riv File in Rive.app
Version: 1.0 — Production Ready Target: Rive Editor (rive.app) +
@rive-app/canvasruntime Date: March 2026 Based on: Vitto Animation Bible v8, SVG Prototype v9
1. Overview
This document specifies exactly how to build Vitto's animated avatar in Rive's editor. The character is a steampunk aviator cat with 14 emotional states, each with unique continuous micro-animations, color palettes, and personality behaviors.
Key deliverable: A single .riv file containing:
- One artboard:
VittoAvatar(260x280 units) - One state machine:
MoodController - 14 mood animation states + idle loops per mood
- Smooth transitions with processing beats between all states
- Mouse-tracking eye input for gaze direction
2. Artboard Setup
Canvas
- Name:
VittoAvatar - Size: 260 x 280 units
- Background: Transparent (host app controls background)
- Frame rate: 60fps target
Layer Order (back to front)
1. tail — Bone-driven path, stroke only
2. ears_group — Left/right ear pairs (outer + inner)
3. head — Main ellipse with fur texture fill
4. cheek_bumps — Two subtle ellipses for face volume
5. goggles — Forehead goggles group (frames, lenses, bridge, rivets)
6. headphones — Headband arc + ear pads group
7. scarf — Patterned neck scarf with tassels
8. blush_spots — Two pink ellipses (opacity animated)
9. eyes_group — Left/right eye assemblies
10. nose — Small triangular path
11. mouth_group — Mouth curves, open mouth, tongue, teeth
12. whiskers — 6 line elements (3 per side)
13. eyebrows — 2 curved paths (opacity animated)
14. particles_layer — Emitter system for sparkles/stars
3. Character Construction
3.1 Head & Body
Head ellipse: cx:130, cy:152, rx:82, ry:76
- Fill: 3-stop radial gradient (highlight → base → shadow)
- Default palette:
#b8a898 → #7a6a5a → #3a2a1a - Apply noise/grain texture overlay for fur feel
Cheek bumps: Two ellipses for volume
- Left:
cx:60, cy:158, rx:16, ry:22, opacity 0.35 - Right:
cx:200, cy:158, rx:16, ry:22, opacity 0.35 - Same gradient fill as head
3.2 Ears (Bone-Driven)
Each ear = outer triangular path + inner triangular path. Use bones so ears can be rotated/translated independently.
Left ear bone at (68, 100):
- Outer:
M68,100 L38,18 L102,72Z— head gradient fill - Inner:
M72,90 L48,28 L96,72Z— ear inner gradient, opacity 0.6 - Inner gradient:
#d4a8a0 → #a87070
Right ear bone at (192, 100):
- Outer:
M192,100 L222,18 L158,72Z - Inner:
M188,90 L212,28 L164,72Z
Per-mood ear positions (expressed as path target shapes — see Section 5 for full data).
3.3 Eyes (Critical — 80% of Emotional Work)
Each eye is a complex assembly. Use clipping masks for eyelid closure.
Eye structure (left eye at translate(98, 136), right at translate(162, 136)):
eye_assembly/
├── clip_mask (ellipse: rx:26, ry:22 — animated for blink/squint)
├── eye_white (ellipse: rx:24, ry:22)
│ └── Fill: radial gradient rgba(248,244,255,0.98) → rgba(235,230,250,0.85)
├── iris (ellipse: rx:14.5, ry:17)
│ ├── Fill: radial gradient #4488cc → #1a3060
│ └── Inner ring detail: stroke rgba(255,255,255,0.15), 0.8w
├── pupil (ellipse: rx:5, ry:12, fill: #06060c)
│ └── Cat slit shape — vertical ellipse
├── shine_primary (circle: r:3.5, cx:-7, cy:-7, white, opacity 0.95)
├── shine_secondary (circle: r:1.8, cx:5, cy:3, white, opacity 0.4)
└── shine_tertiary (circle: r:0.8, cx:-2, cy:8, white, opacity 0.6)
Eye animation properties (all must be independently animatable):
| Property | Range | What It Controls |
|---|---|---|
ewRy |
0-24 | Eye white vertical radius (blink/squint) |
irRx, irRy |
8-18 | Iris size |
puRx, puRy |
2-8 / 6-16 | Pupil size (dilation) |
puCx, puCy |
-6 to +6 | Pupil position (gaze direction) |
clip_ry |
0-22 | Clip mask height (eyelid closure) |
shine_scale |
0-1.5 | Eye shine size multiplier |
Eye shine rules:
- Shines track pupil position (offset from pupil center, not fixed)
- Shines scale with eye openness:
eyeOpenScale = max(0.2, min(1, clip_ry / 15)) - Shines pulse during inspired/celebratory (scale oscillation)
3.4 Goggles (Static with Subtle Animation)
Aviator goggles rest on forehead. Mostly static but shift with head tilt.
Left goggle: Circle frames at (90, 92), r:13, stroke #8b7355, 2.8w
- Lens fill:
rgba(200,170,80,0.15) - Reflection arc on top
- Two rivets at edges (r:1.2, fill #7a6a4a)
Right goggle: Circle frames at (170, 92), r:13
- Same structure as left
Bridge: Line from (103,92) to (157,92), stroke #8b7355, 2.2w
- Center rivet at
(130, 92)
Straps: Short lines connecting to head edges
3.5 Headphones (Bone-Driven)
Slight bounce with head movement.
Headband: Arc path M80,75 Q130,40 180,75
- Stroke #5c3a1e, 3.2w
- Metallic accent overlay: rgba(184,134,11,0.4)
Ear pads: Ellipses at (65,140) and (195,140), rx:11, ry:14
- Outer: #5c3a1e, opacity 0.85
- Inner cushion: #3a2a1a, opacity 0.6
- Shine highlight
Connection bands: Lines from headband endpoints to ear pads
3.6 Scarf
Patterned neck scarf with tassels.
Main shape: Path defining curved collar area
- Fill: linear gradient top→bottom
- Default:
#8b6f47 → #5a4a3a - Pattern dots overlay (subtle circles)
Tassels: Triangular path hanging below
3.7 Mouth
Resting: Two curved paths forming a subtle cat smile
- Left:
M130,178 Q118,188 108,180 - Right:
M130,178 Q142,188 152,180
Open mouth group (opacity animated):
- Dark ellipse at
(130, 190), rx:16, ry:12 - Inner tone ellipse
Tongue (opacity animated):
- Curved path + tip ellipse at
(130, 196)
Teeth (opacity animated):
- Zigzag path for small fangs
3.8 Whiskers
6 line elements, 3 per side. Starting points fixed, endpoints animated.
| Whisker | Start | Default End |
|---|---|---|
| w1 (top-left) | (75, 155) | (45, 148) |
| w2 (mid-left) | (75, 168) | (40, 170) |
| w3 (bot-left) | (75, 181) | (45, 192) |
| w4 (top-right) | (185, 155) | (215, 148) |
| w5 (mid-right) | (185, 168) | (220, 170) |
| w6 (bot-right) | (185, 181) | (215, 192) |
3.9 Tail
Bone-driven curved path, stroke only (8w, round cap).
- Default:
M200,240 Q240,220 248,190 Q254,165 238,155 - Uses head gradient, opacity 0.7
- Continuous sway animation (speed varies by mood)
4. State Machine: MoodController
4.1 Inputs
| Input Name | Type | Range | Purpose |
|---|---|---|---|
moodIndex |
Number | 0-13 | Primary mood selector |
gazeX |
Number | -1 to 1 | Mouse/gaze horizontal position |
gazeY |
Number | -1 to 1 | Mouse/gaze vertical position |
intensity |
Number | 0-1 | Animation intensity (reduced motion support) |
isSpeaking |
Boolean | — | Triggers mouth movement overlay |
4.2 Mood Index Mapping
| Index | Mood | Description |
|---|---|---|
| 0 | neutral | Relaxed idle — ear flicks, gentle sway |
| 1 | focused | Hunting mode — scanning pupils, still body |
| 2 | cheerful | Happy purring — body bounce, love-blinks |
| 3 | empathetic | Gentle concern — slow nods, leaning in |
| 4 | curious | Head tilt — dramatic tilts, darting pupils |
| 5 | analytical | Processing — micro-nods, reading pupils |
| 6 | celebratory | PARTY — full bounce, ear wiggles, sparkles |
| 7 | apologetic | Guilt — drooping head, guilty peeks |
| 8 | inspired | Lightbulb — growing excitement, pulsing |
| 9 | urgent | Alert — rapid vibration, adrenaline pupils |
| 10 | playful | Wiggly — figure-8 sway, tongue pops, winks |
| 11 | confused | Tilted — extreme tilts, asymmetric eyes |
| 12 | proud | Smug — chin up, slow blinks, chest puff |
| 13 | sleepy | Drowsy — progressive closing, snap-awakes |
4.3 State Machine Architecture
┌─────────────┐
│ Entry │
└──────┬──────┘
│
┌──────▼──────┐
│ Neutral │ ← Default state
│ (Idle Loop)│
└──────┬──────┘
│
┌────────────┼────────────┐
│ │ │
moodIndex moodIndex moodIndex
changes changes changes
│ │ │
┌────────▼──┐ ┌─────▼────┐ ┌───▼─────────┐
│ ProcessBeat│ │ProcessBeat│ │ ProcessBeat │ ... (for all 14)
│ → Focused │ │→ Cheerful │ │→ Celebratory│
│ (Idle Loop)│ │(Idle Loop)│ │ (Idle Loop) │
└───────────┘ └──────────┘ └─────────────┘
Each state transition goes through a Processing Beat blend:
- NOTICE (0-80ms): Eyes widen briefly
- PROCESS (80-200ms): Slight head squash
- REACT (200-400ms): Eyes move to new expression
- COMMIT (400-520ms): Ears, mouth, head tilt follow
- SETTLE (520-700ms): Whiskers, blush, tail settle
4.4 Transition Blend Times
| From → To | Blend Duration | Easing |
|---|---|---|
| Any → Any (default) | 700ms | Ease-in-out |
| Any → Urgent | 300ms | Spring |
| Any → Celebratory | 500ms | Bounce |
| Any → Sleepy | 1200ms | Ease-out (slow fade) |
| Sleepy → Any | 400ms | Spring (snap awake) |
5. Per-Mood Animation Specifications
5.1 Color Palettes Per Mood
Each mood has 4 gradient systems that transition together:
| Mood | Face Gradient | Ear Inner | Iris Gradient | Scarf Gradient |
|---|---|---|---|---|
| neutral | #b8a898→#7a6a5a→#3a2a1a | #d4a8a0→#a87070 | #4488cc→#1a3060 | #8b6f47→#5a4a3a |
| focused | #a0a8b8→#5a6a7a→#1a2a3a | #bcc8d8→#7a8aa8 | #3366aa→#0a2040 | #6a7a8a→#3a5060 |
| cheerful | #d4b888→#b8864a→#6a4020 | #f0d4c8→#d8a894 | #55aadd→#2a5080 | #c89860→#a05a30 |
| empathetic | #c0a8b8→#8a6a7a→#3a1a2a | #e4d0e0→#b8a8c0 | #5577bb→#1a2a55 | #9a7a9a→#6a5a7a |
| curious | #a8c8b8→#5a8a7a→#1a4a3a | #c8ffe8→#80c8a8 | #44aaaa→#1a4050 | #6a9a8a→#3a6a5a |
| analytical | #a8b8c8→#5a6a8a→#1a2a4a | #c0d0e0→#8898b0 | #3366bb→#0a2050 | #6a7a9a→#3a5070 |
| celebratory | #e8d088→#c8a040→#7a6010 | #fff0c0→#e0c880 | #cc8833→#804010 | #d4a840→#a07a20 |
| apologetic | #c0b0c8→#8a7a9a→#3a2a4a | #d8c8e0→#a898b8 | #7766aa→#3a2a60 | #8a7a9a→#5a4a6a |
| inspired | #c8a8d8→#8a5aaa→#3a1a5a | #e8d0f0→#c0a0d8 | #8855cc→#4a1a80 | #a870c8→#7a40a0 |
| urgent | #d8a0a0→#aa4040→#5a1010 | #f0c0c0→#d08080 | #cc3333→#801010 | #c04040→#8a2020 |
| playful | #a8d8b8→#5aaa7a→#1a5a3a | #c8f0d8→#80c8a0 | #33aa66→#105030 | #6aaa7a→#3a7a5a |
| confused | #d8c0a0→#aa8850→#5a4a10 | #f0e0c0→#d0b880 | #aa7733→#604010 | #c0a050→#8a7030 |
| proud | #e0d0a0→#b8a050→#6a5a10 | #f8f0c8→#d8c880 | #aa8833→#604810 | #c8a850→#8a7830 |
| sleepy | #b8b0c0→#7a7088→#2a2030 | #d0c8d8→#a098b0 | #6660aa→#2a2050 | #8a8098→#5a5068 |
5.2 Eye Geometry Per Mood
| Mood | ewRy (openness) | irRx/irRy | puRx/puRy | Notes |
|---|---|---|---|---|
| neutral | 22 | 14.5/17 | 5/12 | Default relaxed |
| focused | 11 | 13.5/10 | 2.5/8 | Narrowed slits, small pupils |
| cheerful | 10 | 12.5/8 | 4/6 | Squinted with joy, lower lid up |
| empathetic | 24 | 15.5/20 | 8.5/16 | Wide, huge dilated pupils |
| curious | 23 (L), 19 (R) | 14.5/18 | 6.5/14 | Asymmetric! Left wider |
| analytical | 14 (L), 20 (R) | 13/12 | 3/9 | Left squinted, right open |
| celebratory | 6 | 11/5 | 5/4 | Nearly shut with joy |
| apologetic | 18 | 13/15 | 5/11 | Looking down/away |
| inspired | 25 | 16/19 | 7/15 | Wide and getting wider |
| urgent | 24 | 14/18 | 3/14 | Wide, pinpoint pupils |
| playful | 20 (L), 14 (R) | 14/16 | 5/12 | Right eye winking |
| confused | 22 (L), 16 (R) | 14/17 | 5.5/12 | Asymmetric sizes |
| proud | 14 | 13/11 | 4/9 | Half-closed, smug |
| sleepy | 8 | 12/6 | 4.5/5 | Nearly closed, heavy lids |
5.3 Continuous Micro-Animation Loops (Per State)
Each mood state in Rive should contain a looping timeline with these behaviors:
neutral (Idle Loop)
0.0s: Ear flick left (sharp 5px up, settle over 200ms)
2.0s: Gentle head sway (2.5deg sine at 0.4Hz, continuous)
3.0s: Ear flick right (mirror of left)
4.0s: Slow blink (both eyes, 200ms down, 200ms up)
6.0s: Chin stretch (head lifts 2px, settles over 500ms)
8.0s: Loop
Continuous: Tail sway at 0.8x speed, whisker 1.5px oscillation
focused (Idle Loop)
0.0s: Pupil scan start (linear left-to-right, 5px range, 1s duration)
1.0s: Pupil scan return (linear right-to-left, 1s)
2.0s: Ear burst twitch (both ears 3px, 6x rapid, 500ms total)
4.0s: Loop
Continuous: Body PERFECTLY still, whiskers pushed forward (3.5 value), blink rate near zero
cheerful (Idle Loop)
0.0s: Body bounce starts (5px vertical at 3Hz)
0.0s: Purring vibration (0.6px horizontal at 16Hz, continuous)
0.8s: Love-blink (both eyes to 0.7 closure, 400ms cycle)
1.5s: Head tilt peak left (7deg)
2.0s: Ears alternate (left up 4px, right down, 2.2Hz/2.8Hz)
2.5s: Love-blink again
3.0s: Head tilt peak right
3.3s: Loop
Continuous: Tail fast 2.5x speed
empathetic (Idle Loop)
0.0s: Slow understanding nod begins (3px down over 1s)
1.0s: Nod returns (1s up)
1.5s: Head tilt (4deg to left, 800ms)
2.0s: Pupils drift to center-down (-0.5 X, 1.5 Y)
3.0s: Head tilt (4deg to right, 800ms)
4.0s: Loop
Continuous: Slow breathing (0.85 base + 0.1 amp at 0.4Hz), body lean 1.5px forward, tail 0.4x
curious (Idle Loop)
0.0s: Head tilt peak right (10deg, snappy)
0.3s: Pupil dart (5px right, snap)
0.5s: Hold (pupils pause 300ms)
0.8s: Double-blink (two quick blinks, 100ms each)
1.0s: Head tilt peak left (10deg, snappy)
1.3s: Pupil dart (5px left, snap)
1.5s: Hold
1.8s: Loop
Continuous: Ears independent (left forward 8px, right back), body leans with tilt 2.5px, tail 1.5x
analytical (Idle Loop)
0.0s: Micro-nod (1.5px down, sharp, 250ms)
0.25s: Micro-nod return (250ms)
0.5s: Reading pupil sweep (left→right 4px, 400ms)
0.9s: Reading pupil drop (2px down, 100ms)
1.0s: Reading pupil return (left→right again, 400ms)
1.5s: Left eye squint cycle begins (winkL to 0.5 over 1.5s)
3.0s: Left eye opens (500ms)
3.5s: Loop
Continuous: Head perfectly level, whiskers forward (3px), tail dead still (0x)
celebratory (Idle Loop)
0.0s: Full body bounce UP (8px, bounce easing, 83ms)
0.08s: Body bounce DOWN (squash: headRx+3, headRy-3)
0.17s: Eyes pop open/shut (0.85 closure, spring easing, 167ms cycle)
0.0s: Ear wiggle (6px, independent L/R at 8Hz)
0.0s: Head sway (6deg, synced with bounce)
0.5s: Sparkle particle burst (3 particles from top)
1.0s: Sparkle burst again
1.5s: Sparkle burst again
2.0s: Loop
Continuous: Eye shines pulse (0.4 amplitude), tail maximum 3.5x speed
apologetic (Idle Loop)
0.0s: Start drooping (head drops 1px)
1.0s: Continue drooping (head at -2px, ears flatten -1px)
2.0s: Guilty peek up (pupils snap to center-up for 500ms)
2.5s: Eyes dart back down-left (pupils to -3, 2.5)
3.0s: Nervous whisker twitch (2px, 200ms burst)
4.0s: Head at -3px, ears at -2px
5.0s: Another guilty peek (briefer, 300ms)
6.0s: Loop (droop resets gently)
Continuous: breathScale 0.92, tail barely moving 0.15x
inspired (Idle Loop — Progressive)
NOTE: This is PROGRESSIVE — values build over time, don't reset each loop!
0.0s: Begin pupil dilation increase (+0.05/s)
0.0s: Begin head lift increase (+0.3px/s)
0.0s: Begin ear perk increase (+0.2px/s)
2.0s: Building vibration starts (grows from 0 to 0.4px)
0.0s: Eye shine pulse (0.5 amplitude at 3.5Hz, continuous)
Caps: pupilDilation max 1.5, headLift max 3, earPerk max 2, vibration max 0.4
Continuous: Tail 1.8x speed
urgent (Idle Loop)
0.0s: Rapid vibration (1.2px X at 22Hz, 1.2px Y at 20Hz)
0.0s: Pupil surge (dilation 0.8→1.3 at 10Hz)
0.0s: Ear swivel (5px at 12/11Hz L/R)
0.0s: Head sharp tilt (3deg at 3Hz)
0.0s: Whisker splay (3px wide + 2px twitch at 18Hz)
All continuous — no distinct phases, pure controlled chaos
Continuous: Breath held tense (0.95), tail 2.8x speed
playful (Idle Loop)
0.0s: Body figure-8 starts (4px X at 2Hz, 4px Y at 2.5Hz)
0.0s: Tilt wiggle (5deg at 1.5Hz)
1.5s: Tongue pop (0.8 opacity, 300ms)
2.0s: Left eye wink (full close 0.95, hold 400ms, open over 300ms)
2.5s: Butt-wiggle (2px side-lean, 500ms)
3.5s: Loop
Continuous: Ears jaunty angles (4px oscillation), tail fast whip 2.5x
confused (Idle Loop)
0.0s: Extreme tilt right (13deg, 600ms)
0.0s: Left eye squints (winkL 0.4), right eye wide
0.6s: SNAP — tilt left (13deg, 200ms — fast!)
0.6s: Switch — right eye squints, left wide
0.8s: Head micro-shake (2deg at 8Hz, 400ms burst)
1.2s: Pupils drift independently (X at 1.5Hz, Y at 2Hz)
1.5s: SNAP back right
2.0s: Loop
Continuous: One ear up one down (5px, switching), tail slow 0.4x
proud (Idle Loop — Progressive)
0.0s: Chin begins rising (builds to 5px headLift over 4s)
1.5s: First slow deliberate blink (0.7 closure, 800ms total — SLOW)
3.5s: Smug tilt settles (constant 3deg offset)
5.0s: Second deliberate blink
Caps: headLift max 5px
Continuous: breathScale 1.05 (chest puff), whiskers forward 2px, tail dignified 0.5x
sleepy (Idle Loop — Progressive)
NOTE: Eyes progressively CLOSE over time!
0.0s: Eyes begin closing (winkL/winkR climb toward 0.95)
0.0s: Head nodding begins (2.5px oscillation at 0.5Hz)
3.0s: Nodding amplitude grows (to 4.5px)
5.0s: SNAP-AWAKE! Eyes suddenly open (wink drops to 0.1), hold 500ms
5.5s: Eyes begin slowly closing again (2s to return to near-shut)
7.0s: Yawn (mouth opens, tongue flash 0.6 for 400ms)
7.5s: Continue drowsy cycle
Continuous: Slow breathing (0.3Hz), ears droop (-3px progressive), tail barely moving 0.08x
6. Gaze Tracking System
Input Processing
The runtime provides gazeX and gazeY as normalized values from -1 to 1 (mouse position relative to avatar center).
Pupil Response
pupil_offset_x = gazeX * 5 * (1 - mood_intensity)
pupil_offset_y = gazeY * 4 * (1 - mood_intensity)
Where mood_intensity reduces gaze tracking when the mood's own pupil animation is strong:
- focused: 0.8 (minimal tracking — scanning overrides)
- curious: 0.6 (some tracking, but darting overrides)
- sleepy: 0.9 (barely tracks — too tired)
- neutral: 0 (full tracking)
- Others: 0.3 (mostly tracks, mood adds slight offset)
Eye Shine Tracking
Shines offset in the OPPOSITE direction of pupil movement (light reflection):
shine_offset_x = -pupil_offset_x * 0.3
shine_offset_y = -pupil_offset_y * 0.3
7. Speaking Overlay
When isSpeaking is true, overlay a mouth animation:
- Mouth curves alternate between open and closed states
- Open mouth ellipse opacity oscillates 0→0.6→0 at ~4Hz
- Very subtle jaw drop (head squash: headRy -= 2px)
- This BLENDS with the current mood — it doesn't override mood mouth
8. Particle System (Rive Emitters)
Celebratory Sparkles
- Type: Circle, r:2, white, opacity 0.8
- Emission: 8 bursts of 3 particles, every 250ms
- Velocity: Random spread, -1.2 Y (upward drift)
- Gravity: 0.08 downward
- Lifetime: 140 frames
- Origin: Top of head area (130, 80)
Inspired Stars
- Type: Circle, r:1, gold
rgba(255,200,100,0.7) - Emission: Continuous, 1 per 200ms
- Velocity: Upward float, slight random X
- Lifetime: 100 frames
- Origin: Around head area
Playful Bounces
- Type: Circle, r:1.5, gold
rgba(184,134,11,0.6) - Emission: Bursts of 2, every 500ms
- Velocity: Random spread, stronger upward
- Gravity: 0.08 (bouncy feel)
- Lifetime: 120 frames
9. Aura/Glow System
Each mood has an ambient glow around the character:
Implementation: Radial gradient behind the character, animated opacity.
| Mood | Aura Color | Glow Color | Pulse Speed |
|---|---|---|---|
| neutral | rgba(122,106,90,.28) | rgba(122,106,90,.2) | 3s |
| focused | rgba(90,106,122,.3) | rgba(90,106,122,.22) | 2.5s |
| cheerful | rgba(184,134,74,.38) | rgba(200,160,100,.28) | 2s |
| celebratory | rgba(200,160,64,.45) | rgba(220,180,80,.35) | 1.2s |
| urgent | rgba(200,80,80,.4) | rgba(220,60,60,.32) | 1.2s |
| sleepy | rgba(100,90,120,.2) | rgba(80,70,100,.15) | 5s |
Aura animation: Scale oscillation (1.0 → 1.13) with opacity fade (0.15 → 0.45), at mood-specific pulse speed.
10. Reduced Motion Support
When intensity input is set to 0:
- All continuous micro-animations stop
- Mood transitions use simple crossfade (300ms)
- No particles
- No vibration/shaking
- Tail stays still
- Aura pulse stops (static glow)
Intermediate values (0-1) scale all animation amplitudes proportionally.
11. Export Requirements
File Spec
- Format: .riv (Rive binary)
- Runtime target:
@rive-app/canvasv2.x - Artboard: Single artboard "VittoAvatar"
- State machine: Single "MoodController"
- Max file size target: < 500KB
Runtime Integration
The Angular component will:
- Load the .riv file
- Create a Rive instance with the "MoodController" state machine
- Set
moodIndexinput when mood changes - Update
gazeX/gazeYon mouse move - Toggle
isSpeakingduring AI responses - Set
intensitybased onprefers-reduced-motionmedia query
12. Testing Checklist
Before shipping, verify:
- All 14 moods render correctly with distinct visual identity
- Transitions between ALL mood pairs are smooth (14x14 = 196 combinations)
- Processing beats are visible (eyes lead, ears follow, details settle)
- Asymmetric moods work (curious, confused, playful, analytical)
- Eye shines scale with eye openness
- Mouse gaze tracking works smoothly
- Particles emit and clean up properly
- Color palettes transition smoothly
- Reduced motion mode disables all movement
- File size is under 500KB
- 60fps maintained on mid-range devices
- No visual glitches during rapid mood switching