Avatar
Expressive persona avatars that bring AI companions to life through color, animation, and emotional states.
Persona Avatars
Each AI persona has a distinct avatar color that reflects their personality and expertise.
<div class="avatar avatar--ferni">
<span class="avatar-initial">F</span>
</div>
<div class="avatar avatar--maya">
<span class="avatar-initial">M</span>
</div>
Sizes
Avatars come in four sizes to fit different contexts.
<div class="avatar avatar--ferni avatar--xs">...</div>
<div class="avatar avatar--ferni avatar--sm">...</div>
<div class="avatar avatar--ferni avatar--md">...</div>
<div class="avatar avatar--ferni avatar--lg">...</div>
<div class="avatar avatar--ferni avatar--xl">...</div>
Speaking State
When a persona is speaking, the avatar displays a pulsing glow effect to indicate activity.
<div class="avatar avatar--ferni avatar--speaking">
<span class="avatar-initial">F</span>
</div>
Listening State
When a persona is listening, the avatar shows a subtle breathing animation.
<div class="avatar avatar--ferni avatar--listening">
<span class="avatar-initial">F</span>
</div>
Thinking State
When a persona is processing or thinking, a shimmer effect indicates cognitive activity.
<div class="avatar avatar--peter avatar--thinking">
<span class="avatar-initial">P</span>
</div>
Avatar with Ring
Add a colored ring for emphasis or to indicate selection.
<div class="avatar avatar--ferni avatar--ring">
<span class="avatar-initial">F</span>
</div>
CSS Custom Properties
Avatar styling uses design tokens for consistent theming.
| Token | Description | Default |
|---|---|---|
--avatar-size-xs |
Extra small size | 24px |
--avatar-size-sm |
Small size | 32px |
--avatar-size-md |
Medium size (default) | 48px |
--avatar-size-lg |
Large size | 72px |
--avatar-size-xl |
Extra large size | 96px |
--persona-{name} |
Persona background color | See personas page |
--persona-{name}-glow |
Persona glow color | rgba variant |
Full CSS
.avatar {
--avatar-size: var(--avatar-size-md, 48px);
width: var(--avatar-size);
height: var(--avatar-size);
border-radius: var(--radius-full);
display: flex;
align-items: center;
justify-content: center;
font-family: var(--font-display);
font-weight: var(--font-weight-semibold);
color: var(--text-inverse);
transition: all var(--duration-normal) var(--ease-ease-out);
}
/* Persona colors */
.avatar--ferni { background: var(--persona-ferni); }
.avatar--peter { background: var(--persona-peter); }
.avatar--maya { background: var(--persona-maya); }
.avatar--alex { background: var(--persona-alex); }
.avatar--jordan { background: var(--persona-jordan); }
.avatar--nayan { background: var(--persona-nayan); }
/* Sizes */
.avatar--xs { --avatar-size: 24px; font-size: 10px; }
.avatar--sm { --avatar-size: 32px; font-size: 12px; }
.avatar--md { --avatar-size: 48px; font-size: 18px; }
.avatar--lg { --avatar-size: 72px; font-size: 28px; }
.avatar--xl { --avatar-size: 96px; font-size: 36px; }
/* Speaking state - pulsing glow */
.avatar--speaking {
animation: avatar-pulse 1.5s ease-in-out infinite;
}
@keyframes avatar-pulse {
0%, 100% { box-shadow: 0 0 0 0 var(--persona-glow, rgba(74, 103, 65, 0.4)); }
50% { box-shadow: 0 0 20px 8px var(--persona-glow, rgba(74, 103, 65, 0.4)); }
}
/* Listening state - breathing */
.avatar--listening {
animation: avatar-breathe 3s ease-in-out infinite;
}
@keyframes avatar-breathe {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
/* Thinking state - shimmer */
.avatar--thinking {
animation: avatar-shimmer 2s ease-in-out infinite;
}
@keyframes avatar-shimmer {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
/* Ring */
.avatar--ring {
box-shadow: 0 0 0 3px var(--bg-primary), 0 0 0 5px currentColor;
}
Accessibility
Color Contrast
Avatar initials meet WCAG AA contrast requirements against all persona colors.
Reduced Motion
All animations respect prefers-reduced-motion and will be disabled when requested.
Screen Readers
Include proper aria-label attributes to describe the persona to assistive technology.
<div
class="avatar avatar--ferni"
role="img"
aria-label="Ferni, Chief of Staff"
>
<span class="avatar-initial" aria-hidden="true">F</span>
</div>