# ThinkingBox

> Max's thinking box: the running account of what he thought, which tools he called, what he sent and what came back.

## Facts

- **Product**: Max
- **Family**: Agents
- **Global**: `window.DigitalCrew.ThinkingBox`
- **Source**: `max-agent: src/features/agent/ui/thinking-box.tsx`
- **Import in the app**: `import { ThinkingBox } from "@/features/agent/ui/thinking-box";`
- **Live preview**: /design/components/thinking-box/preview.html
- **Page**: /design/components/thinking-box

## Guidelines

It stays open while he works and folds to one line once he answers.

**Use it for** the working-out above an agent reply. It styles correctly only inside an element with the `maxchat` class.

**What you provide**
- `steps`: `ThinkingStep[]` from `buildThinkingSteps`: thoughts `{ kind: "thought", id, text, live }` and tools `{ kind: "tool", id, name, label, phase, input?, output?, errorText? }`, where `phase` is running, done or error.
- `streaming`: whether Max is still working.

**Anatomy** (`.mx-think*`)
- A 1px `--mx-line` border and a 10px radius, tinted `--mx-ai` purple while live.
- The 12.5px/550 header names the running tool with a shimmering title and a seconds counter. Afterwards it reads "Here's how I got there" with a summary such as "2 thoughts · 3 tools".
- Thoughts are 12.5px italic `--mx-ink-3` behind a 2px rule, purple while live.
- Tool rows are 8px-radius cards with a 7px dot: purple and pulsing while running, `--mx-new` green when done, red when failed. A click reveals "Sent" and "Got back" (or "Error") in an 11px mono block, at most 220px tall.

**Motion**: the box rises in with `mx-in` (6px, 0.3s, `cubic-bezier(0.16, 1, 0.3, 1)`). The title shimmers on a 2000ms loop, and the spark and running dots pulse. Reduced motion stops all three.

**Don't** hide failed calls or cut payloads silently: long results end with a visible marker.

## API

```ts
export declare const ThinkingBox: any;
```

## Example

```html
<div id="root" class="p-6"></div>
<script>
(function () {
  var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
  var LIVE = [
    { kind: "thought", id: "t1", live: false, text: "She asked for fintech CFOs in Paris who changed jobs this quarter. Start with LinkedIn, then enrich what comes back." },
    { kind: "tool", id: "call-1", name: "linkedin_search_people", label: "LinkedIn search people", phase: "done",
      input: { title: "CFO OR \"Finance Director\"", industry: "Financial Services", location: "Île-de-France", changed_jobs_within_days: 90 },
      output: { total: 14, returned: 14 } },
    { kind: "tool", id: "call-2", name: "enrich_contacts", label: "Enrich contacts", phase: "running", input: { prospect_ids: 14 } },
    { kind: "thought", id: "t2", live: true, text: "Three profiles have no company domain yet; I'll flag them instead of guessing." }
  ];
  var DONE = [
    LIVE[0], LIVE[1],
    { kind: "tool", id: "call-2", name: "enrich_contacts", label: "Enrich contacts", phase: "done", input: { prospect_ids: 14 }, output: { enriched: 11, missing_domain: 3 } },
    { kind: "tool", id: "call-3", name: "crm_create_list", label: "CRM create list", phase: "error", input: { name: "Fintech CFOs, Paris" }, errorText: "A list with this name already exists." },
    { kind: "thought", id: "t3", live: false, text: "Added them to the existing list instead." }
  ];
  function Label(text) { return h("div", { className: "mb-1.5 text-[11px] font-medium uppercase tracking-wide text-muted-foreground" }, text); }
  function App() {
    return h("div", { className: "maxchat mx-auto max-w-[620px] gap-4 rounded-2xl border border-border/60 p-5", style: { height: "auto" } },
      h("div", null, Label("While Max works"), h(DC.ThinkingBox, { steps: LIVE, streaming: true })),
      h("div", null, Label("After he answers (click to reopen)"), h(DC.ThinkingBox, { steps: DONE, streaming: false }),
        h("p", { className: "text-[14.5px] leading-relaxed", style: { color: "var(--mx-ink-2)" } },
          "I found 14 CFOs who started a new role since July. Data found for 11 of 14; the other 3 need a company domain.")));
  }
  ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>
```

## More in Agents

- [AgentAvatar](/design/components/agent-avatar.md): 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.
- [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.
- [ToolStatusIndicator](/design/components/tool-status-indicator.md): Compact dot, label and state rows that report tool activity in the onboarding and meetings chats.
