Skip to content
RU
Scale
Density
Theme
Accent

Agent layer

Turn

One step of an exchange. Everything else in this layer shows work; a turn is what the work happens inside — an answer is not a paragraph but a container for steps, a diff, an approval, a budget.

The component
You14:02
Add a share bar above the history strip.
Agent14:02
I'll put it above the strip and let one legend key both.
Markup
<div class="inst-stack inst-stack--loose">
  <div class="inst-turn" data-from="user">
    <div class="inst-turn-head"><span class="inst-turn-who">You</span><span>14:02</span></div>
    <div class="inst-turn-body">Add a share bar above the history strip.</div>
  </div>
  <div class="inst-turn">
    <div class="inst-turn-head"><span class="inst-turn-who">Agent</span><span>14:02</span></div>
    <div class="inst-turn-body">I'll put it above the strip and let one legend key both.</div>
    <div class="inst-turn-actions">
      <button class="inst-btn inst-btn--xs inst-btn--icon inst-btn--ghost" type="button" aria-label="Copy"><svg class="inst-icon" aria-hidden="true"><use href="#i-copy"/></svg></button>
      <button class="inst-btn inst-btn--xs inst-btn--icon inst-btn--ghost" type="button" aria-label="Retry"><svg class="inst-icon" aria-hidden="true"><use href="#i-refresh"/></svg></button>
      <button class="inst-btn inst-btn--xs inst-btn--icon inst-btn--ghost" type="button" aria-label="More"><svg class="inst-icon" aria-hidden="true"><use href="#i-more"/></svg></button>
    </div>
  </div>
</div>

Contract

What Required Why
data-from="user" on the person's turn yes The machine's turn is the default. Marking both would mean an attribute value with nothing to declare
A name in inst-turn-who yes Colour and indent are not carriers: the recess is the same film in every theme, and a screen reader gets neither
A time no Useful in a long thread, noise in a short one
inst-turn-actions keeps its space yes, if present Hover may strengthen an element, but it may not bring one into being. The row is laid out either way, so nothing moves under the cursor; the buttons fade in, and @media (hover: none) gives them at full strength where there is no cursor to reveal them with. A row that is not laid out at all does not exist on a touchscreen
A thread as a list no Turns are siblings in an inst-stack--loose; the kit does not add a second name for a column

The person's turn is recessed, the machine's has no surface at all: the answer is the one that holds steps, diffs and approvals, and each of those brings its own frame. A surface under them would put a plate inside a plate.

Accessibility

Who spoke Named in the text, not by the surface. The recess is decoration and reaches no assistive technology
Streaming An answer still arriving carries the caret; the text itself is the announcement
Actions Real buttons with labels. They stand in the flow, so Tab reaches them in reading order

Composition

An answer that did work

In context
Agent14:02
Added, and the legend now keys the tones.
edit src/data.css 0.4 s
.inst-share { display: flex; }
Markup
<div class="inst-turn">
  <div class="inst-turn-head"><span class="inst-turn-who">Agent</span><span>14:02</span></div>
  <div class="inst-turn-body">Added, and the legend now keys the tones.</div>
  <details class="inst-step" open>
    <summary class="inst-step-head">
      <span class="inst-step-twist"></span>
      <span class="inst-dot" data-tone="ok"></span>
      <span class="inst-step-name">edit</span>
      <span class="inst-step-sub">src/data.css</span>
      <span class="inst-step-meta">0.4 s</span>
    </summary>
    <div class="inst-step-body">
      <div class="inst-code">.inst-share { display: flex; }</div>
    </div>
  </details>
  <div class="inst-turn-actions">
    <button class="inst-btn inst-btn--xs inst-btn--ghost" type="button">Copy</button>
    <button class="inst-btn inst-btn--xs inst-btn--ghost" type="button">Retry</button>
  </div>
</div>

API

Classes
NameWhat it does
class
inst-turnOne step of an exchange
inst-turn-headWho and when, in the type of metadata
inst-turn-whoThe name inside that line
inst-turn-bodyWhat was said. It may hold any component of this layer
inst-turn-actionsCopy, retry, branch. The row always holds its space; the buttons come up under the cursor, and stand at full strength wherever there is no cursor
Attributes
NameValueWhat it does
attribute
data-fromuserThe person's turn, and only that one: it is recessed, the machine's turn is the default and bare
Tokens
NameValueWhere from
token
--surface-recessedlight-dark(oklch(0 0 0 / 0.060), oklch(1 0 0 / 0.050))one across every cell
--radius-lg12pxbase +4: scale
--pad-panelvar(--space-5)base +14: density · scale
--space-36pxone across every cell
--text-xs0.78125rembase +4: scale
--text-mutedlight-dark(var(--n-8), var(--n-6))one across every cell
--text-secondarylight-dark(var(--n-9), var(--n-5))one across every cell
--weight-medium600one across every cell
--leading-ui1.4one across every cell

Why the kit works this way — the constitution · Open source under MIT, github.com/keshon/instrument