Skip to content

FreeIn reviewv1.0.0

Tool Call Card

A tool call an agent made: name and status on a line, arguments and result under a disclosure.
npx shadcn@latest add @vibebox/tool-call-card

Controls

<ToolCallCard />

About

Trust in an agent comes from seeing what it did. The card is closed by default so a long run stays readable, and open on demand.

Use it when

  • An assistant calls tools the user may want to inspect.

Skip it when

  • The results are large: link to a detail page.

Install

  1. 1Add the VibeBox registry to components.json:
    {
      "registries": {
        "@vibebox": "https://motion.vibeboxph.com/r/{name}.json"
      }
    }
  2. 2Add the component with the shadcn CLI:
    npx shadcn@latest add @vibebox/tool-call-card
  3. 3Use it:
    import { ToolCallCard } from "@/components/vibebox/tool-call-card";
    
    <ToolCallCard accent="#7c5cff" />

AI prompt

Everything an AI coding tool needs to rebuild this component the way it looks here: colours, fonts, the art it draws, props and rules.

Read the prompt
Build the VibeBox Motion component "Tool Call Card" (AI and agents) in a Next.js App Router project with Tailwind CSS v4.

What it is
- A tool call an agent made: name and status on a line, arguments and result under a disclosure.
- How an agent shows its work: the tool's name in a mono face with a status dot (success, error or pulsing for running), and a native disclosure that opens to the arguments and the result. It uses `details`, so it works without script and by keyboard.

Install
- `npx shadcn@latest add @vibebox/tool-call-card`
- Registry: add `"@vibebox": "https://motion.vibeboxph.com/r/{name}.json"` to components.json, then run the command. The source lands in `components/vibebox/tool-call-card` and is yours to edit.

Visual spec
- Colours (the VibeBox spectrum, the same in light and dark):
    - --spectrum-1: #00c5fc (cyan)
    - --spectrum-2: #1d6ef0 (blue)
    - --spectrum-3: #5225ed (indigo)
    - --spectrum-4: #e434dc (magenta)
    - --spectrum-5: #fd3aa9 (pink)
    - --spectrum-6: #f98472 (coral)
    - --spectrum-7: #fcbe72 (amber)
- Ink surface (dark): background #05070c, card #0a0d15, text #f5f6fa, muted text #a3abbd, border rgba(255,255,255,0.08).
- Paper surface (light): background #f3f0ea, card #fbfaf7, text #0c0e14, muted text #4a4f5c, border rgba(12,14,20,0.12).
- Fonts:
    - Display and body: Figtree (400, 500, 600, 700), falling back to ui-sans-serif, system-ui.
    - Emphasis: Fraunces italic, for one or two words of a heading.
    - Labels and code: JetBrains Mono (400, 500), uppercase labels with 0.14em tracking.
- Shape: radius 8 to 12px on cards and panels; pills may be fully round. Hairline borders, soft glow instead of heavy shadow.
- Motion: animate transform and opacity only; fast ease-out (cubic-bezier(0.16, 1, 0.3, 1)), 140ms for micro-interactions, 320 to 520ms for reveals.

Art and media
- Built from HTML, CSS and inline SVG only; no image files or video.

Props
- `name`: `string` (default "search_bookings"). The tool's name.
- `status`: `"success" | "error" | "running"` (default "success"). How the call went.
- `args`: `Record<string, string>`. The arguments, as key and value text.
- `result`: `string`. The result, as text.
- `accent`: `string` (default "blue"). The accent colour: blue, violet, emerald, amber, rose, or any CSS colour. It sets --app-accent on the root, so a parent can set it once for a whole screen.
- `className`: `string`. Merged with cn(); give it a width.

Behaviour and access
- Reduced motion: Nothing animates on its own.
- Keyboard: Every control is a native element in reading order.
- Screen readers: Semantic elements with accessible names; decorative marks are hidden.
- Touch: Targets are 36 px or larger; nothing depends on hover.
- Budget: about 0 KB of JavaScript, WebGL none, GPU none. It pauses while off screen.

Theming
Everything reads `--app-accent` (set by the `accent` prop, or by a parent) and the mode's tokens, so light and dark and any brand colour work without code changes. Pass a named accent or any CSS colour; Launchpad sets it once per app from the client's theme.

Usage
```tsx
import { ToolCallCard } from "@/components/vibebox/tool-call-card";

<ToolCallCard accent="#7c5cff" />
```

Notes
Add the VibeBox Motion Tool Call Card with `npx shadcn@latest add @vibebox/tool-call-card`. Stack one card per call, in order. Set the brand colour once with `--app-accent` on a parent (or the `accent` prop). It follows light and dark through the tokens; keep the licence header.

Rules
- Keep the licence header on every installed file.
- Original code only: do not copy components from other libraries, and do not add GSAP.
- Use tokens for colour, type and radius; no hard-coded brand values.
- Server Components by default; `"use client"` only for the island.

Code

1 files
components/vibebox/tool-call-card/index.tsx
/**
 * VibeBox Motion · Tool Call Card
 * Copyright (c) 2026 VibeBox. Licensed under the VibeBox Motion Free License:
 * https://motion.vibeboxph.com/license
 * Use it in unlimited personal, commercial and client projects.
 * Do not sell or redistribute it as a component, kit, template or builder.
 */
import { cn } from "@/lib/utils";
import { accentStyle } from "@/lib/vibebox/app-accent";

export type ToolCallCardProps = { name?: string; status?: "success" | "error" | "running"; args?: Record<string, string>; result?: string; accent?: string; className?: string };

/** A tool call an agent made: its name and status on top, the arguments and the result under a disclosure. */
export function ToolCallCard({ name = "search_bookings", status = "success", args = { date: "2026-10-16", party: "2" }, result = "2 openings: 10:30, 14:15", accent, className }: ToolCallCardProps) {
  const label = status === "success" ? "Done" : status === "error" ? "Failed" : "Running";
  return (
    <details data-vb="tool-call-card" style={accentStyle(accent)} className={cn("group rounded-xl border border-border bg-card text-small", className)}>
      <summary className="flex cursor-pointer list-none items-center gap-2.5 px-3.5 py-2.5 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring [&::-webkit-details-marker]:hidden">
        <span aria-hidden="true" className={cn("size-2 rounded-full", status === "success" && "bg-[var(--app-accent)]", status === "error" && "bg-destructive", status === "running" && "bg-[var(--app-accent)] motion-safe:animate-pulse")} />
        <code className="font-mono text-[0.82rem]">{name}</code>
        <span className="ml-auto text-caption text-muted-foreground">{label}</span>
        <svg viewBox="0 0 12 12" aria-hidden="true" className="size-3 text-muted-foreground transition-transform group-open:rotate-180" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><path d="m2.5 4.5 3.5 3.5 3.5-3.5" /></svg>
      </summary>
      <div className="grid gap-2 border-t border-border px-3.5 py-3">
        <dl className="grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 font-mono text-[0.78rem]">
          {Object.entries(args).map(([k, v]) => (
            <div key={k} className="contents"><dt className="text-subtle-foreground">{k}</dt><dd>{v}</dd></div>
          ))}
        </dl>
        <p className={cn("rounded-md px-2.5 py-1.5 font-mono text-[0.78rem]", "bg-[color-mix(in_oklab,var(--app-accent)_14%,transparent)]")}>{result}</p>
      </div>
    </details>
  );
}

Props

PropTypeDefaultDescription
namestring"search_bookings"The tool's name.
status"success" | "error" | "running""success"How the call went.
argsRecord<string, string>—The arguments, as key and value text.
resultstring—The result, as text.
accentstring"blue"The accent colour: blue, violet, emerald, amber, rose, or any CSS colour. It sets --app-accent on the root, so a parent can set it once for a whole screen.
classNamestring—Merged with cn(); give it a width.

Accessibility and motion

Keyboard
Every control is a native element in reading order.
Screen readers
Semantic elements with accessible names; decorative marks are hidden.
Touch
Targets are 36 px or larger; nothing depends on hover.
Reduced motion
Nothing animates on its own.

Edge cases and limits

  • Results are plain text; format them before passing them.
  • A vertical timeline with two ticked steps, one spinning step and one queued step

    A timeline of what an agent is doing: done steps ticked, the running one spinning, the rest queued.

    AI and agents · Server

  • A chat with an accent-coloured message on the right and grey replies on the left

    A chat conversation: your messages in the accent, replies on a card, and a typing indicator.

    AI and agents · Server

  • A rounded prompt box with a model chip at the bottom left and an accent send button

    A prompt box that grows with its text, with a model chip and a send button that wakes when there is text.

    AI and agents · CSS

↑ ↓ to move↵ to openesc to close