Flux 2.0

Component

Assistant panel

A side panel for conversing with Runa: messages, cited sources, suggestions and a prompt.

Plain-text source, for agents and clipboard use: /components/source/assistant-panel.txt

When to use it

Gives an AI assistant a consistent, quiet place beside the work it is helping with. The conversation is a log, so new messages are announced. Replies cite the records they were drawn from as links, so every claim can be checked. Suggestions offer a first prompt, a disclaimer sits under the prompt field, and Enter sends while Shift and Enter adds a line. The panel says it is working while a reply is pending, and the page supplies the reply.

Not this
Not as the only way to do something the interface could do directly. Not for system notifications; use a Toast. Not with a chat bubble style, an avatar for the assistant, or a typing animation.

Examples

In a booking

Type a message or press a suggestion. On this page, a sample reply arrives after a moment.

html
<aside class="flux-assistant" data-flux-assistant="Runa" aria-labelledby="runa-title">
  <header class="flux-assistant__header">
    <span class="flux-assistant__mark" aria-hidden="true"></span>
    <div class="flux-assistant__heading">
      <h2 class="flux-assistant__title" id="runa-title">Runa</h2>
      <p class="flux-assistant__subtitle">Booking KB-104931</p>
    </div>
    <button class="flux-assistant__close" type="button" aria-label="Close Runa"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4.5 4.5l7 7M11.5 4.5l-7 7" /></svg></button>
  </header>
  <div class="flux-assistant__log" role="log" aria-label="Conversation with Runa">
    <div class="flux-assistant__message flux-assistant__message--user">
      <p class="flux-visually-hidden">You</p>
      <p>Which rooms are still unconfirmed?</p>
    </div>
    <div class="flux-assistant__message">
      <p class="flux-visually-hidden">Runa</p>
      <p>Six double rooms at Hotel Rangá for 14–16 September are still on request. The supplier was asked three days ago and has not replied.</p>
      <ul class="flux-assistant__sources" aria-label="Sources">
        <li><a class="flux-assistant__source" href="#"><span class="flux-assistant__source-ref">KB-104931</span>Supplier request</a></li>
        <li><a class="flux-assistant__source" href="#"><span class="flux-assistant__source-ref">CT-2026-118</span>Hotel Rangá contract</a></li>
      </ul>
    </div>
  </div>
  <div class="flux-assistant__suggestions" role="group" aria-label="Suggestions">
    <button class="flux-button flux-button--secondary flux-button--sm" type="button" data-flux-assistant-suggestion>Draft a reminder to the hotel</button>
    <button class="flux-button flux-button--secondary flux-button--sm" type="button" data-flux-assistant-suggestion>Find alternative hotels</button>
  </div>
  <form class="flux-assistant__composer">
    <label class="flux-field__label" for="runa-prompt">Ask Runa</label>
    <div class="flux-assistant__field">
      <textarea class="flux-textarea" id="runa-prompt" rows="1" aria-describedby="runa-disclaimer"></textarea>
      <button class="flux-button flux-assistant__send" type="submit" aria-label="Send"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 13V3.5M3.75 7.5L8 3.25l4.25 4.25" /></svg></button>
    </div>
    <p class="flux-assistant__disclaimer" id="runa-disclaimer">Runa can be wrong. Check figures against the booking before you send them.</p>
  </form>
</aside>

Working

While a reply is pending, the log holds a status with a small Spinner and a sentence. The script adds it on send and removes it when the page responds.

You

Find alternative hotels near Hella for 14 September.

Runa is working on it
html
<div class="flux-assistant__log" role="log" aria-label="Conversation with Runa">
  <div class="flux-assistant__message flux-assistant__message--user">
    <p class="flux-visually-hidden">You</p>
    <p>Find alternative hotels near Hella for 14 September.</p>
  </div>
  <div class="flux-loading" role="status">
    <span class="flux-spinner flux-spinner--sm" aria-hidden="true"></span>
    <span>Runa is working on it</span>
  </div>
</div>

Anatomy

PartDescription
HeaderThe product mark in the agents accent, the assistant’s name, the context it is working in, and a close button.
Logrole="log" holding the messages, scrolling on its own.
MessageThe assistant’s replies sit on the panel ground; the person’s messages sit right-aligned on layer-02, as a bubble with a small tail towards their side.
SourcesLinks under a reply, each with a mono reference.
SuggestionsSmall secondary buttons with a starting prompt. Hidden once the conversation starts, if the page chooses.
ComposerA labelled textarea that grows with its text, a send button, and the disclaimer.

API

NameKindDescription
flux-assistantclassThe panel, an aside labelled by its title.
data-flux-assistantattributeThe assistant’s name. Wires sending, suggestions and the working status.
flux-assistant__header | __mark | __heading | __title | __subtitle | __closeclassThe header and its parts. The mark is graphic only.
flux-assistant__logclassOn the role="log" element.
flux-assistant__messageclassA reply. Start it with a visually hidden sender name.
flux-assistant__message--userclassThe person’s message.
flux-assistant__sources | __source | __source-refclassThe cited sources under a reply.
flux-assistant__suggestionsclassThe suggestion row. Hidden when empty.
data-flux-assistant-suggestionattributeOn a suggestion button: sends its text as a message.
flux-assistant__composer | __field | __send | __disclaimerclassThe prompt form and its parts.
flux-assistant-messageelementEvent dispatched on send, with detail.message and detail.respond({ paragraphs, sources }). Sources are { label, ref, href }.

States

StateTreatment
EmptyThe log is empty and the suggestions offer a first prompt.
WorkingA status with a small Spinner and a sentence, until the reply arrives.
RepliedThe reply, with its sources as links.

Keyboard

KeysAction
EnterIn the prompt, sends the message.
Shift EnterIn the prompt, adds a new line.
TabMoves through sources, suggestions, the prompt and send.

Accessibility

  • The log is role="log", so new messages are announced politely as they arrive.
  • Each message starts with a visually hidden sender, so the conversation reads as a dialogue.
  • The prompt has a visible label; the disclaimer is bound to it with aria-describedby.
  • The agents accent is a graphic mark only. All text uses text roles.

Tokens

The tier-3 and tier-2 tokens this component binds to. Change the token, not the component.

  • --flux-assistant-width | -height | -bg | -border
  • --flux-assistant-padding | -gap | -user-bg | -tail-size
  • --flux-assistant-mark | -mark-size | -meta
  • --flux-assistant-source-bg | -source-hover

Do and don’t

Do

  • Cite the records a reply was drawn from, with their references.
  • Say what the assistant is working on, in the subtitle.
  • Let the person check and edit anything the assistant drafts before it is sent.

Don’t

  • Do not stream text in with a typing effect or animate the reply.
  • Do not give the assistant a face, a coloured bubble or a glow.
  • Do not use the product accent for text.