Cube mascot
ProAn isometric cube mascot where three shaded faces and a painted-on face show what the assistant is doing. It turns a quarter turn in eased steps while thinking, prints lines onto the floor while writing, settles with a sparkle when done, and shakes once on error.
- Give an assistant a recognisable, product-like character that shows it is generating: in a reply header, in a composer, on an image canvas or in an empty state.
- Brands with a geometric, technical feel where a soft blob would feel off.
- Use ai-mascot for a softer, rounder character, or when you need a listening state.
- Use agent-status when people need the steps, tools and elapsed time of a run.
- Do not use it as a progress indicator with a known percentage; use a progress bar.
Installation
Pro source and install commands unlock with a Pro plan.
import { CubeMascot, type CubeStatus } from "@/components/arc/cube-mascot/cube-mascot"; // Inline next to a streaming replyexport function ReplyHeader({ phase }: { phase: "waiting" | "streaming" | "complete" | "failed" }) { const status: CubeStatus = phase === "streaming" ? "writing" : phase === "complete" ? "done" : phase === "failed" ? "error" : "thinking"; return ( <div style={{ display: "flex", alignItems: "center", gap: 8 }}> <CubeMascot status={status} size={24} name="Atlas" /> <span>Atlas</span> </div> );} // Empty state on an image canvas while it generates<CubeMascot status={generating ? "thinking" : "idle"} size={144} name="Atlas" announce /> // Brand colored body with light features<CubeMascot status="writing" size={64} color="#4f6bff" faceColor="white" />CubeMascot
An isometric cube character drawn in SVG from real 3D math: a rounded silhouette, three faces shaded by how they face the light, and a face painted on the front side through its projected plane. Idle tilts, floats and blinks. Thinking turns the cube a quarter turn in eased steps, and the face fades in on the side that arrives at the front. Writing tips the face down while lines print onto the ground in front of it. Done settles with a happy squint and a sparkle. Error shakes once and shows worried brows. Status changes blend from the pose on screen over 420ms, never a hard cut.
status"idle" | "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: a larger cube in the frame, bolder eyes, no mouth, shadow or printed lines.colorstring–Any CSS color for the cube body. Defaults to the accent. The top and shaded side are mixed from it.faceColorstring–Any CSS color for the eyes, brows and mouth. Defaults to the accent foreground.groundbooleantrueThe contact shadow and the lines printed while writing. Drawn at 56px and up.pausedbooleanfalseFreeze on the current frame. The cube also pauses by itself off screen and in background tabs, and resumes without a jump.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 mascot that carries status, not for decorative copies.onStatusChange(status: CubeStatus) => 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 --cube-body, --cube-ink, --cube-top, --cube-front, --cube-side, --cube-line, --cube-shadow or --cube-sparkle here to restyle.styleCSSProperties–Inline style on the root span.- None
- The mascot is a status image and takes no focus. Pair it with a real control when people act on what it shows.
- The SVG has role img and a label built from name and status, for example "Atlas, writing", which updates with every state.
- With announce, status changes are read in a polite live region outside the image. Use it on one mascot per view.
- Status is never motion alone: each state changes the face (eyes up, eyes down, happy squint, worried brows and frown) and the label. Show a text status next to it where the state matters.
- Under reduced motion every state is a still pose that switches in place.
- The cube is real 3D: eight corners are rotated (yaw, roll, pitch, then a fixed 32 degree camera) and projected each frame. The silhouette is their convex hull with rounded corners, used as a clip, so the outline stays soft while edges between faces stay exact.
- Each face is shaded by its normal against a light from the upper left, interpolating between three anchors (top, front, side), so a face turning away darkens continuously.
- Thinking holds for .5s, then turns a quarter turn over .8s with a cubic ease in and out, rising slightly and leaning into the turn. A cube looks identical after 90 degrees, so the end of each step is the start of the next and the loop has no seam. The face on the leaving side fades as it turns edge on; the face on the arriving side fades in and its eyes open as it reaches the front.
- Writing prints a line every 360ms: each line slides out from under the face along the ground for 1.44s and only fades in and out, and its length changes while it is invisible. Eyes sweep slowly and the cube nods once per four lines.
- Idle is a sum of slow sines with incommensurate periods (tilt, sway, float, glance), so it never repeats or restarts. Blinks come every 2.6 to 4.9s, sometimes twice, and take 170ms.
- Done dips once and settles while the eyes pass through a closed line into the squint and the sparkle grows and turns in, then twinkles slowly. Error shakes 3.5 times in .56s under a squared envelope that reaches rest with zero velocity.
- A status change blends every pose value from the frame on screen to the new state over 420ms (240ms into error) with an ease in and out. A change caught mid turn keeps turning forward instead of unwinding. Nothing bounces.
- A fixed square of size px that never reflows its parent. Vector art stays crisp at any device pixel ratio.
- Below 56px the compact drawing frames the cube tighter and enlarges the eyes so they read at 24px.
- One requestAnimationFrame loop per cube writes SVG attributes directly, and only when they change, so React does not re-render per frame; the self-playing loop sets state once per state.
- The loop stops off screen (IntersectionObserver) and in hidden tabs, and its clock only runs while visible, so it resumes on the same frame.
- Under reduced motion nothing loops; the drawing repaints only on status changes.
- About thirty small SVG nodes and one clip path, no filters, masks or gradients.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Map your assistant's real phases to status: waiting for the first token is thinking, streaming is writing, finished is done, failed is error, otherwise idle.
- Keep thinking short in real use and switch to writing on the first token.
- Use size 24 to 32 inline in a message header or composer, 40 to 64 in a panel header, 96 to 160 in an empty state or on a generating canvas.
- Set name to the assistant's name. Turn announce on for one mascot only. Leave status unset only for showcases.
- The default body is the accent, which is near neutral grey in Arc; the shading anchors come from it, so any accent or color prop works in light and dark.
The full library index for assistants is at /llms.txt.