Agent surfaces
MaxChat
A static rendition of .maxchat, the surface every Max agent speaks through: the Max chat, the Ask Max panel, the meetings assistant and the onboarding chat.
Guidelines#
Why it looks different: agent surfaces use their own cool 260° neutrals (mx-* tokens), the purple accent-ai for AI activity and the green accent-new for live status, ink-filled primary buttons instead of orange, Instrument Serif for the empty-state greeting, and prose messages without bubbles. It is scoped under .maxchat, so it never leaks into the app's shadcn theme.
Anatomy: a blurred header (34px face, name with a green status dot, "online · head of sales", tools badge); a 760px thread column; user messages right-aligned in italic mx-ink-2; Max's replies as 14.5px prose (chat-message) with a collapsible thinking box listing thoughts and tool calls (running pulses purple, done green, failed red); a 22px-radius composer with round attach, voice and a 34px ink send button; an 11.5px foot note stating what needs confirmation.
Rules from the source: Max always says what it will do and asks before anything goes out; human-in-the-loop cards (.mx-confirm) carry the draft and the choice. The component itself needs Max's chat runtime, so this card shows its markup with the real classes rather than the live component.
Facts#
| Group | Agent surfaces |
|---|---|
| Product | Max |
| Kind | Showcase page (tokens and patterns, not a single export) |
Example#
The code of the preview above: plain React.createElement against window.DigitalCrew, with realistic data.
<style>
.demo { height: 600px; display: grid; grid-template-columns: 1fr 1fr; }
.demo > .maxchat { height: 600px; border-right: 1px solid var(--mx-line); }
.face { width: 30px; height: 30px; border-radius: 50%; object-fit: cover; object-position: 50% 22%; display: block; }
.face--head { width: 34px; height: 34px; }
.face--big { width: 96px; height: 96px; margin: 0 auto 18px; box-shadow: 0 0 0 4px color-mix(in oklch, var(--mx-ai) 20%, transparent), 0 18px 40px -18px oklch(0% 0 0 / 0.45); }
</style>
<div class="demo">
<div class="maxchat">
<header class="mx-head">
<img class="face face--head" src="/design/assets/Agents/max-carter.webp" alt="">
<div class="mx-head__identity">
<div class="mx-head__name">Max <span class="mx-head__dot"></span></div>
<div class="mx-head__sub">online · head of sales</div>
</div>
<span class="mx-mcp mx-mcp--connected"><span class="mx-mcp__dot"></span>Tools connected</span>
<button class="mx-head__clear" type="button">Clear</button>
</header>
<div class="mx-body">
<div class="mx-thread">
<div class="mx-thread__inner">
<div class="mx-row mx-row--user">
<div class="mx-bubble mx-bubble--user">Find fintech CFOs in Paris who changed jobs this quarter.</div>
</div>
<div class="mx-row mx-row--max">
<div class="mx-row__av"><img class="face" src="/design/assets/Agents/max-carter.webp" alt=""></div>
<div style="display:grid;gap:10px;min-width:0">
<div class="mx-think">
<button type="button" class="mx-think__head" aria-expanded="true">
<span class="mx-think__title">Searched LinkedIn and enriched 14 profiles</span>
<span class="mx-think__meta">3 tools · 6s</span>
</button>
<div class="mx-think__body">
<div class="mx-think__thought">Job changes in the last 90 days, title contains CFO or Finance Director, company in fintech, Île-de-France.</div>
<div class="mx-think__tool mx-think__tool--done"><button type="button" class="mx-think__tool-head"><span class="mx-think__dot"></span><span class="mx-think__tool-name">LinkedIn people search</span><span class="mx-think__tool-state">done</span></button></div>
<div class="mx-think__tool mx-think__tool--done"><button type="button" class="mx-think__tool-head"><span class="mx-think__dot"></span><span class="mx-think__tool-name">Enrich contacts</span><span class="mx-think__tool-state">done</span></button></div>
</div>
</div>
<div class="mx-bubble mx-bubble--max">I found <strong>14 CFOs</strong> who started a new role since July. Data found for 11 of 14; the other 3 need a company domain. Want me to draft an opener for each and hold them for your review?</div>
</div>
</div>
</div>
</div>
</div>
<div class="mx-foot">
<div class="mx-composer">
<div class="mx-composer__row">
<button class="mx-attach" type="button" aria-label="Attach file or image"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66L9.41 17.41a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg></button>
<textarea rows="1" placeholder="Ask Max…" aria-label="Message Max">Yes — keep them under 90 words</textarea>
<button class="mx-send" type="button" aria-label="Send"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5M5 12l7-7 7 7"/></svg></button>
</div>
</div>
<p class="mx-foot__note">Max can open app pages directly. Outreach requires your confirmation.</p>
</div>
</div>
<div class="maxchat">
<div class="mx-body">
<div class="mx-thread">
<div class="mx-empty">
<img class="face face--big" src="/design/assets/Agents/max-carter.webp" alt="">
<h2 class="mx-empty__title">Hey, I’m <em>Max</em>.</h2>
<p class="mx-empty__sub">Your head of sales. Tell me what you need — sourcing prospects, running LinkedIn and email campaigns, reading the numbers — and I’ll drive it. I’ll always check with you before anything goes out.</p>
<div class="mx-chips">
<button class="mx-chip" type="button">Build a list of fintech CFOs</button>
<button class="mx-chip" type="button">Why did replies drop this week?</button>
<button class="mx-chip" type="button">Draft a follow-up for Northwind</button>
</div>
</div>
</div>
</div>
</div>
</div>