# AgentAvatar

> A Digital Worker's face as a muted, looping video in a rounded square, framed and glowing in the agent's brand colour, with an optional live dot.

## Facts

- **Product**: Crew OS
- **Family**: Agents
- **Global**: `window.DigitalCrew.AgentAvatar`
- **Source**: `digitalcrew-orchestrator: components/dc/index.ts`
- **Import in the app**: `import { AgentAvatar } from "@/components/dc";`
- **Live preview**: /design/components/agent-avatar/preview.html
- **Page**: /design/components/agent-avatar

## Guidelines

**Use it for** worker cards and headers in the Crew OS control centre (Ongoing missions), next to the worker's name and role.

**What you provide**: `videoUrl` (required; the agent loop, e.g. `AGENT_MEDIA[agent].url`), `color` (required; a hex such as `var(--dc-camille)` resolved to `#ec4899`), `name` (for `aria-label="<name> avatar"`), `size` (`sm`, `md` default, `lg`), `isActive` (default false).

**Anatomy**: `sm` 48px with a 2px frame, `md` 64px / 2px, `lg` 96px / 3px, all `rounded-xl`, `object-cover`. Behind it a `blur-lg` copy of the colour at 20% opacity (30% in dark mode). The live dot sits at the bottom-right corner, 4px outside: `bg-green-500`, 12 / 16 / 24px by size, a 2px `border-card` ring and a `animate-ping` halo at 75%.

**Behaviour**: the video autoplays muted, looped and inline (`play()` is retried on mount). There is no fallback: with an empty `videoUrl` or a video that fails to load you get the empty coloured frame, as Claire shows in the second row (her loop is not in this system yet). The ping halo does not check reduced motion.

**Don't** pass a CSS variable string as `color` (it is concatenated into the glow), use it for people who are not Digital Workers (use [`Avatar`](/design/components/avatar.md)), or show the live dot for workers that are idle.

## API

```ts
interface AgentAvatarProps {
    videoUrl: string;
    color: string;
    name: string;
    isActive?: boolean;
    size?: "sm" | "md" | "lg";
}
export declare function AgentAvatar({ videoUrl, color, name, isActive, size }: AgentAvatarProps): any;
```

## Example

```html
<div id="root" class="p-6"></div>
<script>
(function () {
  var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
  function tok(name) { return getComputedStyle(document.documentElement).getPropertyValue("--dc-" + name).trim(); }
  var V = { camille: "/sophie.mp4", sophie: "/design/assets/Agents/videos/sophie.mp4", max: "/design/assets/Agents/videos/max.mp4", kate: "/design/assets/Agents/videos/kate.mp4", andre: "/design/assets/Agents/videos/andre.mp4" };
  function Cell(p) {
    return h("div", { className: "grid justify-items-center gap-2" },
      h(DC.AgentAvatar, { videoUrl: p.url, color: tok(p.agent), name: p.name, size: p.size, isActive: !!p.active }),
      h("div", { className: "text-center" }, h("p", { className: "text-sm font-medium" }, p.name), h("p", { className: "text-muted-foreground text-xs" }, p.note)));
  }
  function App() {
    return h("div", { className: "grid gap-8" },
      h("div", { className: "flex items-end gap-8" },
        h(Cell, { agent: "camille", url: V.camille, name: "Camille", note: "sm", size: "sm" }),
        h(Cell, { agent: "camille", url: V.camille, name: "Camille", note: "md", size: "md" }),
        h(Cell, { agent: "camille", url: V.camille, name: "Camille", note: "lg · active", size: "lg", active: true })),
      h("div", { className: "flex items-end gap-8" },
        h(Cell, { agent: "sophie", url: V.sophie, name: "Sophie", note: "md", size: "md" }),
        h(Cell, { agent: "max", url: V.max, name: "Max", note: "md · active", size: "md", active: true }),
        h(Cell, { agent: "kate", url: V.kate, name: "Kate", note: "md", size: "md" }),
        h(Cell, { agent: "andre", url: V.andre, name: "André", note: "md", size: "md" }),
        h(Cell, { agent: "claire", url: "", name: "Claire", note: "no video yet", size: "md" })));
  }
  ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>
```

## More in Agents

- [AgentSkillTag](/design/components/agent-skill-tag.md): A tiny chip naming one of a Digital Worker's skills, tinted with that worker's colour.
- [AskMaxAction](/design/components/ask-max-action.md): A contextual "Ask Max" button.
- [CrewAgents](/design/components/crew-agents.md): The Digital Crew's eight agents, each one colour broken out of the ink: the palette ramp, the gradient, the role and the skills the public site gives them.
- [EquipmentBadge](/design/components/equipment-badge.md): A small chip showing one piece of a Digital Worker's desk equipment as an emoji, with or without its label.
- [MaxRoster](/design/components/max-roster.md): Max's 24 Digital Workers in their seven teams, each with its face (**AgentFace**) and accent dot.
- [OAuthRequestCard](/design/components/oauth-request-card.md): A "Connect HubSpot" or "Connect Notion" card that an agent drops into the chat.
- [ThinkingBox](/design/components/thinking-box.md): Max's thinking box: the running account of what he thought, which tools he called, what he sent and what came back.
- [ToolStatusIndicator](/design/components/tool-status-indicator.md): Compact dot, label and state rows that report tool activity in the onboarding and meetings chats.
