Xzero UI
Pro library

Ghost mascotPro

A floating ghost mascot whose soft sheet ripples at the hem while it hovers. It blinks when idle, turns toward you to listen, fades a little translucent while thinking, draws a tiny pen line while writing, smiles with a sparkle when done and wobbles once on an error.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/ghost-mascot
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/ghost-mascot

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { GhostMascot, type GhostStatus } from "@/components/xzero/ghost-mascot/ghost-mascot";

// Inline next to a streaming reply
export function ReplyHeader({ phase }: { phase: "waiting" | "streaming" | "complete" | "failed" }) {
  const status: GhostStatus = phase === "streaming" ? "writing" : phase === "complete" ? "done" : phase === "failed" ? "error" : "thinking";
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
      <GhostMascot status={status} size={24} name="Atlas" />
      <span>Atlas</span>
    </div>
  );
}

// Empty state: the classic pale sheet
<GhostMascot status="idle" size={160} tone="sheet" name="Atlas" />

// On an image canvas while it generates
<GhostMascot status={generating ? "thinking" : "done"} size={64} announce />

// Brand color sheet with light eyes
<GhostMascot status="listening" size={96} color="#7747ff" eyeColor="white" />

API reference

GhostMascot

A floating ghost drawn in SVG: a soft sheet with a rippling hem, a quiet form shade and two simple eyes. Six states. Idle floats, blinks and glances around. Listening comes forward with wide eyes and a small head tilt. Thinking drifts up, turns translucent and looks up at a small swirl that curls in and out. Writing leans toward a line it writes with a tiny pen, eyes on the tip. Done lifts with happy eyes and a sparkle. Error wobbles once, sinks and droops its eyes. Status changes blend from the pose on screen over 400ms, never a hard cut.

PropTypeDefaultDescription
status"idle" | "listening" | "thinking" | "writing" | "done" | "error"–What the assistant is doing. Leave unset to play through every state on a loop (the docs demo).
sizenumber96Width and height in px, from 24 (inline next to a message) to 160 (empty state). Below 56 a compact drawing takes over: tighter framing, bigger eyes, heavier swirl, pen and line, no shadow.
tone"accent" | "sheet" | "ink""accent"Sheet color from the theme: the accent with accent-foreground eyes, a pale raised surface with a hairline and foreground eyes (marks keep the accent), or the foreground ink with background eyes.
colorstring–Any CSS color for the sheet. Overrides tone; the eyes become a dark mix of it unless eyeColor is set.
eyeColorstring–Any CSS color for the eyes.
groundbooleantrueThe soft floating shadow, which shrinks and fades as the ghost rises. Drawn only at 56px and up.
pausedbooleanfalseFreeze on the current frame. The ghost also pauses by itself off screen and in background tabs, and resumes on the same frame.
namestring"Assistant"Used in the accessible label, for example "Atlas, thinking".
labelstring–Overrides the whole accessible label.
announcebooleanfalseAnnounce status changes in a polite live region. Turn it on for the one ghost that carries status, not for decorative copies.
onStatusChange(status: GhostStatus) => void–Called when the self-playing loop (status unset) moves to the next state. Use it to sync a caption or a control.
classNamestring–Class on the root span. Set --ghost-body, --ghost-eye, --ghost-mark, --ghost-shade or --ghost-ground here to restyle.
styleCSSProperties–Inline style on the root span.

Keyboard interactions

KeysAction
NoneThe ghost is a status image and takes no focus. Pair it with a real control when people act on what it shows.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in ai

Guidance for AI tools

Ghost mascot: A floating ghost mascot whose soft sheet ripples at the hem while it hovers. It blinks when idle, turns toward you to listen, fades a little translucent while thinking, draws a tiny pen line while writing, smiles with a sparkle when done and wobbles once on an error. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components