agentic / 06

Specimen

A single user, assistant, system, or tool turn with local status and optional actions. Copy Preview, Code, or Install from the tabs. The raw file and standalone fixture remain below.

Preview

chat-message / statesstatic specimen
Human
Show all

Show me the file before you write it.

Agenthost-model

The exact action is ready for review.

System

The host controls completion.

No runtime required. The host owns state, persistence, and any execution boundary.

Code

chat-message.html
<style>
.au-chat-message {
  --au-message-gap: 12px;
  --au-message-avatar: 30px;
  align-items: start;
  display: grid;
  gap: var(--au-message-gap);
  grid-template-columns: var(--au-message-avatar) minmax(0, 1fr);
  padding: 14px 0;
}

.au-chat-message__avatar {
  align-items: center;
  background: var(--au-surface-muted);
  border: 1px solid var(--au-border-color);
  border-radius: 8px;
  color: var(--au-fg-subtle);
  display: flex;
  font: 600 10px/1 var(--au-font-mono);
  height: var(--au-message-avatar);
  justify-content: center;
  width: var(--au-message-avatar);
}

.au-chat-message__meta {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 5px;
}

.au-chat-message__role {
  color: var(--au-fg);
  font-size: 12px;
  font-weight: 650;
}

.au-chat-message__time,
.au-chat-message__model {
  color: var(--au-fg-subtle);
  font: 10px/1.3 var(--au-font-mono);
}

.au-chat-message__body {
  color: var(--au-fg-muted);
  font-size: 14px;
  line-height: 1.55;
  margin: 0;
}

.au-chat-message__body code {
  color: var(--au-action);
  font: 12px/1.4 var(--au-font-mono);
}

.au-chat-message__details {
  margin: 0;
}

.au-chat-message__details > summary {
  color: var(--au-fg-subtle);
  cursor: pointer;
  display: inline-flex;
  font: 10px/1.3 var(--au-font-mono);
  list-style: none;
  margin-bottom: 6px;
  width: fit-content;
}

.au-chat-message__details > summary::-webkit-details-marker {
  display: none;
}

.au-chat-message__details > summary:focus-visible {
  border-radius: var(--au-radius-sm);
  box-shadow: var(--au-focus-ring);
  outline: 2px solid var(--au-focus);
  outline-offset: 2px;
}

.au-chat-message__actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 8px;
}

.au-chat-message__actions .au-btn {
  --au-btn-height: 28px;
  --au-btn-padding-inline: 8px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  min-height: 28px;
}

.au-chat-message--user .au-chat-message__avatar {
  background: var(--au-action-soft);
  border-color: color-mix(in srgb, var(--au-action) 30%, var(--au-border-color));
  color: var(--au-action);
}

.au-chat-message--system .au-chat-message__body {
  color: var(--au-fg-subtle);
  font-family: var(--au-font-mono);
  font-size: 12px;
}

.au-chat-message--tool {
  border-top: 1px solid var(--au-border-color);
}
</style>

<article class="au-chat-message au-chat-message--assistant">
  <span class="au-chat-message__avatar" aria-hidden="true">au</span>
  <div>
    <div class="au-chat-message__meta">
      <span class="au-chat-message__role">Agent</span>
      <time class="au-chat-message__time">now</time>
      <span class="au-chat-message__model">host-model</span>
    </div>
    <p class="au-chat-message__body">The next action is visible and waiting for a decision.</p>
    <div class="au-chat-message__actions" data-au-part="actions">
      <button type="button" class="au-btn au-btn--ghost au-btn--sm" data-au-action="copy">Copy</button>
      <button type="button" class="au-btn au-btn--ghost au-btn--sm" data-au-action="regenerate">Regenerate</button>
    </div>
  </div>
</article>

Install

head.html
<link rel="stylesheet" href="tokens.css">
<link rel="stylesheet" href="components/chat-message/chat-message.css">

Component contract

Dependencies
tokens.css, chat-message.css, button.css when rendering actions.
States
idle, streaming, success, error, and cancelled are host-rendered with `data-au-state` on the turn.
CSS variables
`--au-message-gap`, `--au-message-avatar`
Events
Native form, focus, and click events. No custom event or runtime is required.
No JavaScript
The semantic article, role, time, body, native details expand, and action buttons remain usable without JavaScript.
Host boundary
The host owns message identity, ordering, status transitions, actions, retry, and any streaming buffer.

Accessibility and security

Keep the state explicit.

Accessibility: Use an article, expose the role as text, keep the time readable, and do not rely on avatar color to convey speaker or status. Security: Treat message text, links, and tool output as untrusted. Escape text before insertion and sanitize any optional rich-text adapter.

Source files

The page is documentation, not a package boundary. Copy the raw files and edit them in your application.