Human handoff
The agent hands a conversation to a person, with what they need to pick it up.
The agent passes a conversation to a person: why it handed off (reason), who has it (assignee,
with a people list for Reassign), when the reply is due (secondsLeft counts down and the bar
empties, turning orange under five minutes), the summary and facts they need to pick it up, and
the message the customer was told (editable in place when you pass onMessageChange). A status
row at the foot says where it stands — neutral while it waits, amber when the person can't take it,
green once they have.
Dana was charged twice for her annual plan on Oct 21 and wants one charge back. The agent confirmed the duplicate, but can't refund more than $500.
Usage
<!-- include core.css + human-handoff.css -->
<div class="hox panel" data-c="human-handoff">
<div class="hox-h">
<span class="hox-ic"><!-- user icon --></span>
<div class="hox-ht"><b>Handed off to a person</b><span class="muted">Refund over $500 needs a person</span></div>
</div>
<!-- who has it, when the reply is due, the context, and the foot row -->
</div>Properties
| Name | Type | Description |
|---|---|---|
reason | string | Why the agent handed off, like "Refund over $500 needs a person". |
assignee | HandoffPerson | null | Who has it, or null while the agent is still finding someone. |
finding | { title; detail? } | The two lines shown while assignee is null. |
people | HandoffPerson[] | The people it can go to instead. Leave it out to hide Reassign. |
onReassign | (person) => void | Called when a row is picked in Reassign. |
secondsLeft | number | Seconds until the reply is due. Whole minutes; orange under five; overdue at 0 or less. |
targetSeconds | number | The whole window, for the bar and the "15 min target" line. Defaults to 900. |
summary | string | What the person needs to pick it up. |
facts | { label; value }[] | A few key facts, as label and value rows. |
link | { label; href?; onClick?; tip? } | A link to the whole conversation. |
message | string | What the agent told the customer. |
messageLabel | string | The label over the message, like "Sent to Dana". |
onMessageChange | (text) => void | Adds Edit: the message turns editable, and Save calls this with the new text. |
edited | boolean | Adds "· edited" to the message label. |
status | HandoffStatus | The foot row: tone (wait | warn | ok), title, detail? and an optional person. |
HandoffPerson is { name; initials?; color?; team?; presence?; tone?: ok \| warn } — name is the
key, tone puts a green or orange dot before the presence.
Theming
Works in light and dark (data-theme="dark") and in the Soft style (data-style="soft"). The card
sits on a surface; the countdown bar, the presence dot and the foot row take their colours from the
--dm-* tokens — amber from the warn tokens under five minutes or when the person is out, green from
the ok tokens once they have it. The two columns stack when the card is narrow.