"Priya Raghavan and Engage" reads as two colleagues. Every other entry in the
trail already answers this — the agent's disc carries a sparkle, its name
carries an AI tag, a person's disc carries their initials — and the exchange
entry was the one place printing bare names, on the screen whose whole claim is
that the work was done autonomously.
So the participants are chips rather than a sentence, and so is the label on
every message, in the preview and in the thread: Priya Raghavan wears her
initials, Engage wears the sparkle and the AI tag, and ops replying by hand
wears their initials too — a person answering in the thread must never be
dressed as the machine. The agent chip opens its card, as it does everywhere
else in the trail; the label inside the preview card stays a span, because the
card is already a button.
The disc's tint and the bubble's tint are the same token, so a chip dropped
into a bubble lost its disc; it is white inside one. `.bub span` narrowed to
direct children other than the attribution row, so the chip's own spans are
not restyled and CallTranscript's plain labels still work.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Implements the design in zurich-kotak-leaddesk across every screen.
Foundation: Source Sans 3 bundled from src/assets/fonts (no Google Fonts
request), 15px root, navy/blue/amber/teal/red palette where blue is the AI,
amber a person, teal the customer and red is reserved for risk; flat white
10px cards on a grey canvas, no shadows.
Shell: 56px navy masthead (Z wordmark, Lead Desk, user), 232px white nav
grouped Needs you / Scheduled / History with coloured count pills and the
closed stages folded.
Overview: the hero says who holds each open lead (stacked bar + legend)
beside the renewals-at-risk card; five KPIs incl. Closed to date; Waiting
on a person queue with owner dots and "N more with the AI"; Pipeline by
stage with owner-coloured bars; Renewal exposure with tabs, dropdown
filters and a Holding it column.
Lead: back button, id line, holder pill; one attention banner (amber your
turn / blocked, red stalled, blue with the AI, teal with the customer) that
carries its button; four facts with a confidence bar; navy steps rail
whose current step takes its holder's colour; timeline as an avatar
gutter with title, stage pill, by-line + AI tag and text-link actions
(See reasoning · N steps, Hear the call, Open thread); side column flows.
Lists: card with search + hide-closed toggle, columns Customer / Stage /
Renewal due / Holding it / Premium / Last activity, stalled rows get a red
inset, closed rows dim, person-gated queues split into Your turn / With the
AI group rows.
src/api/holder.js is the single rule for holder tone + label so the table
cells, the overview and the lead header cannot disagree.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Visual and information-architecture pass across every screen. No API call,
payload, poll, permission rule or workflow mirror changes; forms still render
from the live schema and the timeline's merge/grouping is unchanged (only the
display order is reversible).
Design language
- Ground + white cards with one hairline and one radius; sentence-case
headings; shared primitives in index.css (.card .pill .btn .avatar .live).
- One inline icon set (components/Icon.jsx); no more filled navy/red tiles.
- Read-side labels in api/display.js: roles and enum tokens humanized,
customer initials/tones, money and date formatters. Nothing sent changes.
Shell
- 56px header with brand, global lead search (portfolio rows, "/" to focus)
and identity chip with a human role label.
- Sidebar rows carry icons and a clear active bar; AI roster at the foot,
each opening its remit card.
Login
- Operator copy instead of retail copy; centred sign-in card with show/hide
password; demo persona picker that fills the EMAIL only.
Overview
- "Who holds the work" as four quiet cards that warm only when owed.
- Pipeline flow bar with every stage named beneath it; KPI strip in a card.
- Action rows with chevron / view-only eye; expiry bands filter the table.
Queues
- Filter bar (search, product, channel, expiry band, stalled, hide closed)
and sortable columns, all client-side on the fetched page.
- Avatars, product/channel chips, stage chips for closed leads, tinted
stalled rows, count inline with the title.
Lead
- Avatar + chips in the header; metrics card with the stage rail inside,
and a branch node for Referred / Parked / Lost / Declined.
- Timeline newest-first by default (toggle), the worker's face as the node,
one footer row per entry, AI markdown rendered as bold.
- "AI team on this lead" panel with per-agent step counts; PDF tags on docs.
Forms & dialogs
- Required marked with an asterisk + legend; "Select…" placeholder; dd Mon
yyyy hint under date inputs; open activity form in a titled panel;
one-line dialog footnotes.
Fixes: horizontal overflow at 1024px, boxed "in N days" figure, raw tokens
(sme_underwriter, verbal_call, Rsa), findings cut at "1.".
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The avatars were initials-plus-spark for the machines and bare initials for
people — thin, and it made five differently-skilled agents look like the same
badge in five colours. The convention that reads instantly is icons for
machines, initials for people: the contrast itself tells a human step from an
autonomous one before a name is read, and the symbol says WHICH machine.
Each employee now wears a glyph true to its job — a magnifier for Intake (checks
the lead), a speech bubble for Engage (talks to the customer), a shield for the
Advisor (recommends the cover), an ID badge for KYC (verifies identity), balance
scales for the Referral (prepares a file for a human to weigh). The AI spark
stays at the corner. People keep their initials, which is the right avatar for a
person and now the clear signal that a person, not a machine, did the step.
Verified legible at disc size (20-26px) across all five brand hues.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The app had FIFTY-FOUR distinct font sizes and forty of them sat between
0.58rem and 0.95rem — a three-pixel band. The most-used size was 0.78rem, so
body copy was 12.5px. That is not a hierarchy, it is a fog of small grey text,
and it is the main reason the screen read as a decade old: nothing could be
emphasised because everything was already the same size.
Nine steps now, with real jumps. 12px is the floor and is reserved for
uppercase eyebrows — every one of the 53 declarations sitting there that was
not an eyebrow has been lifted off it. The surfaces people actually read — the
trail's entries, WhatsApp bubbles, field values, table cells — are at body size
rather than meta size.
The hairline cages are gone with them. The lead metrics and the overview KPIs
were seven equal cells in a 1px grid, every value the same size as its label,
which left the reader to do the prioritising themselves on every lead. They are
separated by whitespace now, values at 22px against 12px labels, with premium
and commission larger again: size does the prioritising instead.
Panels breathe at 32px rather than 24, radii went 10/14 -> 12/16/20, borders
dropped to the softer line, and the stage rail, the queue table and the cards
were rebuilt on the same spacing rhythm.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Initials alone do not say a step was autonomous — "EN" reads as a colleague's
badge. On a screen whose whole claim is that the work ran without people, the
one fact every entry has to state is which entries were the machine's. Agent
discs now carry a sparkle, the settled convention for machine-generated work,
so it needs no legend; humans keep a plain disc, because a mark on every actor
would say nothing. Screen readers get "(AI)" said out loud, since they cannot
see it.
The call was the one step nobody could replay from the fields. Everything else
on a lead was typed or derived; this happened out loud, and its outcome sat in
the full file next to the source channel while the words themselves were only
reachable from a button halfway down the trail. It gets its own card, with the
transcript one click from the notes that summarise it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TOOLS ARE VISIBLE NOW. Clicking any agent — in the trail or the "Worked
by" strip — opens a card saying what it is, when it runs, what it can
reach and what it reads. The answer is short and it is the reassuring
kind: four of the five hold no tools at all and reason from the policy
wordings, and the only tool in the roster reads a partner registry.
That answer stopped being true once, silently. Intake held a tool that
could telephone customers, its charter never mentioned it, and it used it
on every lead believing it was a duplicate check (89). Nobody could see
that from any screen. This is the screen that would have shown it — which
is the actual argument for building it, beyond a demo looking better.
Where an agent has no tools the card says so in words rather than showing
an empty section. "No tools" is the single most reassuring fact about
something that writes into an insurance file; a blank reads as missing
data.
The roster is a hand-maintained mirror of the employee config, like
STAGES and ACTIONS, and carries the same hazard: a tool added there and
not here is described wrongly, silently. Named in the file.
THE CONVERSATION WAS EATING THE TRAIL. Every WhatsApp turn was its own
entry — heading, actor, quote box — so a four-message exchange occupied
more of the trail than the entire underwriting chain, and a resend
printed the same sentence four times because the customer sent it four
times. A contiguous run now collapses into ONE entry: a WhatsApp mark, a
count, the latest line, and a link that opens the thread. A second
exchange later in the lead stays separate, because that is a different
episode in the story.
And the actor is right. The channel performs these as the system, so the
trail read "System · Customer Reply" — the opposite of what happened.
It says "the customer" now, in the channel's own green, and the rail dot
takes that colour so a scan shows where the conversation was without
reading a word.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Five of the six asks. The sixth — the whole row as the click target —
shipped in 704afe1 and is already live on both grids.
THE AUDIT TRAIL WAS FROZEN. Timeline fetched the rows once on mount and
never again, so a lead being worked by five agents in three minutes
showed the trail as it was when the page opened — on the one screen whose
job is watching work happen. The rows move to the lead page, which
already polls every 12s, and Timeline becomes presentational. One fetch,
one poll, and the conversation view reads the same rows so the two cannot
disagree.
THE ACCEPTANCE BUTTON OUTLIVED THE ACCEPTANCE. Recording an acceptance
twice is not a loop, a recovery or an alternative — it is meaningless,
and offering it invites someone to overwrite a customer's WhatsApp
acceptance with a worse record of the same event. Gone once
acceptance_ref is set, replaced by a line saying who accepted and when.
THE AGENTS HAD NO FACE. Five of them carry this workflow and the console
named them three different ways — "ai_engage" here, "Engage" there,
"Engage AI" elsewhere — so nobody could see that the thing which called
the customer and the thing which wrote the quote were one worker. One
roster now (api/agents.js): a short name, a colour and two initials each,
used wherever an agent is named. People get a disc too, in grey — a trail
where the machines are decorated and the humans are plain text reads as
though the machines are the important ones, which is backwards on a
screen built for oversight. A "Worked by" strip above the trail shows the
team at a glance.
THE CONVERSATION WAS A LOG, NOT A THREAD. Each turn sat as its own entry
among twenty others. Now one button opens it as a thread — theirs left,
ours right, oldest first — and the footer says plainly which parts it
holds: the quote, the read receipt and the acceptance confirmation are
sent by trigger nodes and never written to a field, so they are not
there. A thread that quietly omitted them would be worse than one that
admits what it is.
CONFIRMING A PREMIUM IS A SIGN-OFF, NOT A TASK. It is the only step
locked to one role and the only one that touches money — an employee that
could mark a premium received could put a customer on risk for a policy
nobody paid for. It sat fourth in a list of six queues. It gets its own
band now, shown only to the role that owns it, amber only when something
is actually waiting: a permanent alert colour on an empty queue teaches
people to stop seeing it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>