Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
Displays user personas in an Agile-friendly visual format with avatar, quote, goals, frustrations, and behaviors.
A web component for displaying user personas in a structured, visual card format. Includes an auto-generated avatar with initials and a deterministic color derived from the name hash, a quote block, and slotted sections for biography, goals, frustrations, and behaviors. Ideal for design documentation, sprint planning boards, and stakeholder presentations.
<user-persona role="Product Manager" age="34" location="San Francisco, CA"> <h2 slot="name">Sarah Chen</h2> <p slot="quote">I need tools that help me stay organized across multiple projects.</p> <p slot="bio">Sarah has 8 years of experience in product management at mid-size SaaS companies.</p> <ul slot="goals"> <li>Streamline team communication</li> <li>Track project progress efficiently</li> </ul> <ul slot="frustrations"> <li>Too many disconnected tools</li> <li>Difficulty getting stakeholder buy-in</li> </ul> <ul slot="behaviors"> <li>Checks dashboards first thing each morning</li> <li>Prefers async communication over meetings</li> </ul></user-persona>
| Attribute | Type | Default | Description |
|---|---|---|---|
role |
string | — | Job title or role description |
age |
string | — | Age displayed as "[value] years old" |
location |
string | — | Geographic location shown with a pin icon |
avatar |
string (URL) | — | Custom avatar image URL. When omitted, initials are generated from the name. |
compact |
boolean | — | Reduces padding, font sizes, and avatar size for denser layouts |
src |
string (URL) | — | URL to JSON file containing persona data. Loads and populates all fields. |
| Slot | Expected Content | Description |
|---|---|---|
name |
<h2> or text |
Full name of the persona. Defaults to "Unnamed Persona" when omitted. |
quote |
<p> or text |
Representative quote displayed in an italic block with a decorative quotation mark. |
bio |
<p> or text |
Background information about the persona |
goals |
<ul> or <ol> |
What the persona wants to achieve. Displayed with a green accent icon. |
frustrations |
<ul> or <ol> |
Pain points and frustrations. Displayed with a red accent icon. |
behaviors |
<ul> or <ol> |
Behavioral patterns and habits. Displayed with a purple accent icon. |
Content values (name, quote) are provided as named slots. State attributes (role, age, location, avatar) remain on the element.
When no avatar URL is provided, the component generates an avatar automatically:
To use a custom image instead, set the avatar attribute to any image URL. The image renders as a circular background-image with center/cover sizing.
<user-persona role="Product Manager" avatar="https://example.com/team/sarah.jpg"> <h2 slot="name">Sarah Chen</h2> <p slot="bio">Uses a custom photo instead of generated initials.</p></user-persona>
Add the compact attribute for a denser layout with smaller padding, reduced font sizes, and a 56px avatar (down from 80px). Useful when displaying multiple personas side by side or in a dashboard grid.
<user-persona role="Frontend Developer" age="28" location="Austin, TX" compact> <h2 slot="name">Alex Rivera</h2> <p slot="quote">I want clean APIs and minimal boilerplate.</p> <ul slot="goals"> <li>Ship features faster</li> <li>Reduce build complexity</li> </ul> <ul slot="frustrations"> <li>Breaking changes in dependencies</li> </ul></user-persona>
Load persona data from a JSON file using the src attribute. All fields are mapped to attributes or cached for rendering.
<user-persona src="/api/personas/sarah.json"></user-persona>
{ "name": "Sarah Chen", "role": "Senior Product Manager", "age": "34", "location": "San Francisco, CA", "avatar": "https://example.com/sarah.jpg", "quote": "I need tools that help me stay organized.", "bio": "Sarah has 8 years of experience in product management.", "goals": ["Streamline communication", "Track progress efficiently"], "frustrations": ["Too many disconnected tools", "Unclear ownership"], "behaviors": ["Checks Slack 30+ times per day", "Prefers async communication"]}
Add data-mock to auto-generate a complete persona with a portrait photo, demographics, quote, and slotted sections. Use data-seed for deterministic results.
<!-- Everything auto-generated --><user-persona data-mock></user-persona> <!-- Deterministic — same seed, same persona --><user-persona data-mock data-seed="PM-1"></user-persona> <!-- Partial override — set what you know, mock the rest --><user-persona data-mock data-seed="eng-1" role="VP of Engineering"> <h2 slot="name">Jordan Rivera</h2></user-persona>
The portrait images come from the faker-js portrait assets (CC0 licensed). The face is deterministic — the same name always shows the same person.
Content values — name and quote — are provided as named slots. State attributes like role, age, and location remain on the element. This separation keeps content in the DOM and metadata in attributes.
<user-persona role="Senior Product Manager" age="34" location="San Francisco, CA"> <h2 slot="name">Sarah Chen</h2> <p slot="quote">I need tools that help me stay organized.</p> <p slot="bio">Sarah has 8 years of experience in product management.</p> <ul slot="goals"> <li>Streamline communication</li> <li>Track progress efficiently</li> </ul> <ul slot="frustrations"> <li>Too many disconnected tools</li> </ul></user-persona>
| Variable | Default | Description |
|---|---|---|
--user-persona-bg |
#ffffff / #1e1e1e |
Card background color |
--user-persona-text |
#1a1a1a / #e8e8e8 |
Primary text color |
--user-persona-muted |
#666666 / #888888 |
Secondary/muted text color |
--user-persona-border |
#e0e0e0 / #333333 |
Card and section border color |
--user-persona-accent |
#0066cc / #6b9fff |
Accent color for role text and bio icon |
--user-persona-card-bg |
#f8f9fa / #252525 |
Section card background (quote block, content sections) |
--user-persona-radius |
16px |
Outer card border radius |
--user-persona-avatar-size |
80px |
Avatar width and height (56px in compact mode) |
--user-persona-goals |
#22c55e / #4ade80 |
Goals section accent color |
--user-persona-frustrations |
#ef4444 / #f87171 |
Frustrations section accent color |
--user-persona-behaviors |
#8b5cf6 |
Behaviors section accent color |
| Event | Detail | When |
|---|---|---|
persona-ready |
{ name, role, age, location } |
Fires after the component renders for the first time |
role="article" with an aria-label of "User persona: [name]"role="img" with aria-label="Avatar for [name]"aria-hidden="true" so screen readers skip itprefers-reduced-motion: reduce by disabling all transitions<user-story> — Agile user story cards referencing personas<user-journey> — Journey maps that link back to persona definitions<empathy-map> — Empathy maps linked via persona-id<impact-effort> — Prioritization matrix for triaging stories<story-map> — Horizontal story mapping for sprint planning