Sounds & Haptics
Ferni communicates through multiple senses. Audio and haptic feedback should feel organic, warm, and intentional—never clinical or mechanical.
Philosophy
Sound
Every sound should feel like it belongs in nature—warm chimes, soft tones, organic textures. Never harsh, never robotic.
Haptics
Touch feedback that feels like communication—breathing rhythms, heartbeats, gentle acknowledgments. Felt, not noticed.
Timing
Synchronize with user actions. Immediate for confirmations, gentle delays for emotional moments. Never jarring.
Sound Library
All sounds are designed to feel warm and organic. Each category serves a specific emotional purpose.
System Sounds
Core application feedback—connection, thinking, session state.
Warm welcome when app launches. Sets the emotional tone.
Voice connection established. Relief and readiness.
Connection dropped. Concern but not alarm.
Ambient thinking sound. Subtle presence while processing.
Celebration Sounds
Moments of joy and achievement—scaled to the win.
Quick win. Task complete, small milestone.
Major achievement. Goal reached, breakthrough moment.
Life milestone. Rare, meaningful, memorable.
Consistency win. 7-day streak, 30-day streak.
New team member unlocked. Arrival, potential, excitement.
Persona Handoff Sounds
Each persona has a unique audio signature for transitions.
Warm, grounding, like coming home
Steady, rhythmic, focused energy
Quick, curious, analytical sparkle
Clear, empathetic, smooth flow
Joyful, bouncy, celebration energy
Deep, resonant, philosophical space
Ambient Sounds
Background textures for extended sessions. User-controlled, very quiet.
Zen Garden
3 min loop -24dBCozy Interior
3 min loop -24dBFocused Calm
2 min loop -30dBNight Mode
5 min loop -36dBHaptic Patterns
Haptics are not decoration—they're communication. Every vibration should feel intentional and human.
Intensity Scale
Organic Patterns
Ferni's signature haptics—breathing, pulsing, living.
Ferni Breath
Core breathing pattern. Warm, grounding, nurturing.
Connection established, presence confirmation
Warm Pulse
Gentle warmth pulse. Emotional acknowledgment.
Empathy moment, understanding
Heartbeat
Connection and love. Deep milestone moments.
Deep connection, milestone
Slow Breath
Extended breath. Calm, wisdom, contemplation.
Sage persona, reflection
Quick Breath
Short energetic breath. Curiosity, discovery.
Researcher energy, eureka
Persona Signatures
Each persona has a unique haptic fingerprint reflecting their personality.
Ferni
Warm, grounding, nurturing—life coach energy
Maya
Steady, rhythmic, reliable—architect energy
Peter
Curious, energetic, quick—researcher energy
Alex
Clear, empathetic, smooth—communicator energy
Jordan
Joyful, bouncy, celebratory—event planner energy
Nayan
Deep, integrative, philosophical—wisdom energy
Emotional Haptics
Haptic responses to detected emotional states. Making the invisible visible through touch.
Empathy
Like a gentle hand on shoulder
warmPulse, 300ms, intensity 3
Encouragement
Supportive energy
quickBreath, 200ms, intensity 2
Understanding
I get it
heartbeat, 500ms, intensity 2
Concern
Calming presence
slowBreath, 400ms, intensity 2
Celebration
Pure joy
bigWin, 400ms, intensity 3
Curiosity
Tell me more
quickBreath, 180ms, intensity 2
Accessibility
Sensory feedback must respect user preferences and never be the only feedback channel.
System Preferences
- Always check
isReduceMotionEnabled - Always check
isHapticsEnabled - Reduce intensity 50% in low power mode
Fallbacks
- Haptics disabled → Visual + audio feedback only
- Audio disabled → Visual + haptic feedback
- Always provide visual confirmation
Principles
- Never make haptics the only feedback
- Always pair with visual or audio
- Provide option to disable all haptics
- Test on real devices, not simulators
Implementation
iOS (Swift)
// Ferni Breath Pattern
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.prepare()
func playFerniBreath() {
let pattern: [Double] = [0.2, 0.4, 0.6, 0.8, 1.0, 0.8, 0.6, 0.4, 0.2, 0]
for (index, intensity) in pattern.enumerated() {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 0.03) {
generator.impactOccurred(intensity: CGFloat(intensity))
}
}
}
Android (Kotlin)
// Ferni Breath Pattern
fun playFerniBreath(vibrator: Vibrator) {
val timings = longArrayOf(0, 30, 30, 30, 30, 30, 30, 30, 30, 30)
val amplitudes = intArrayOf(0, 51, 102, 153, 204, 255, 204, 153, 102, 51)
val effect = VibrationEffect.createWaveform(timings, amplitudes, -1)
vibrator.vibrate(effect)
}
Web (Limited Support)
// Web haptics have limited support
// Use visual pulse as fallback
function playFerniBreath() {
if ('vibrate' in navigator) {
navigator.vibrate([30, 30, 30, 30, 30, 30, 30, 30, 30, 30]);
}
// Always show visual feedback
element.classList.add('pulse-animation');
}