agentic / 12

Installation

tokens.css + ask-user-question.css + button.css
head.html
<link rel="stylesheet" href="tokens.css">
<link rel="stylesheet" href="components/ask-user-question/ask-user-question.css">

Basic

ask-user-question / Basicinteractive

Question 1 of 3

How should the agent resume this plan?

Resume path

Code

ask-user-question.html + ask-user-question.css
ask-user-question
<style>
.au-ask-user-question {
  background: var(--au-surface);
  border: 1px solid var(--au-border-color);
  border-radius: var(--au-radius-xl);
  min-width: 0;
  padding: 16px 16px 12px;
}
.au-ask-user-question__eyebrow,
.au-ask-user-question__progress {
  color: var(--au-fg-muted);
  font: 400 12px/1.3 var(--au-font-sans);
  margin: 0 0 8px;
}
.au-ask-user-question__title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.35;
  margin: 0 0 8px;
}
.au-ask-user-question__options { border: 0; display: grid; gap: 2px; margin: 0; padding: 0; }
.au-ask-user-question__option {
  align-items: center;
  border-radius: var(--au-radius-lg);
  color: var(--au-fg);
  cursor: pointer;
  display: flex;
  gap: 8px;
  min-height: 40px;
  padding: 8px 12px;
}

@media (pointer: coarse) {
  .au-ask-user-question__option {
    min-height: 44px;
  }
}
.au-ask-user-question__option:hover { background: var(--au-surface-hover); }
.au-ask-user-question__option:has(input:checked) { background: var(--au-action-soft); }
.au-ask-user-question__option input { accent-color: var(--au-action); }
.au-ask-user-question__footer {
  align-items: center;
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 8px;
}
.au-ask-user-question__hint {
  color: var(--au-fg-subtle);
  font: 400 12px/1.4 var(--au-font-sans);
  margin-right: auto;
}
.au-ask-user-question[data-au-state="answered"] { opacity: .72; }
.au-ask-user-question[data-au-state="error"] { border-color: color-mix(in srgb, var(--au-danger) 45%, transparent); }

/* --- absorbed: multi/pager chrome --- */
/* agent-ui / approval-pager — first-class component (promoted from host extracts). */
/* 04 Multi-question approval pager */
.au-approval-pager { display: grid; gap: 12px; }
.au-approval-pager__nav {
  align-items: center;
  display: flex;
  gap: 8px;
  justify-content: space-between;
}
.au-approval-pager__dots { display: flex; gap: 8px; }
.au-approval-pager__dot {
  background: var(--au-surface-muted);
  border: 1px solid var(--au-border-color);
  border-radius: 50%;
  height: 8px;
  padding: 0;
  width: 8px;
}
@media (max-width: 640px) {
  .au-approval-pager__dot {
    height: 40px;
    min-width: 40px;
    width: 40px;
  }
}
.au-approval-pager__dot[aria-current="true"] {
  background: var(--au-action);
  border-color: var(--au-action);
}
.au-approval-pager__panel[hidden] { display: none; }
</style>

<form class="au-ask-user-question" method="post" data-au-state="waiting"><p class="au-ask-user-question__progress">Question 1 of 3</p><h3 class="au-ask-user-question__title">How should the agent resume this plan?</h3><fieldset class="au-ask-user-question__options"><legend class="sr-only">Resume path</legend><label class="au-ask-user-question__option"><input type="radio" name="ex-resume" value="preview" checked><span class="au-ask-user-question__option-body"><span class="au-ask-user-question__option-title">Internal preview</span><span class="au-ask-user-question__option-desc">Ship behind a flag</span></span><span class="au-ask-user-question__chip" aria-hidden="true">1</span></label><label class="au-ask-user-question__option"><input type="radio" name="ex-resume" value="public"><span class="au-ask-user-question__option-body"><span class="au-ask-user-question__option-title">Public release</span><span class="au-ask-user-question__option-desc">Open channel</span></span><span class="au-ask-user-question__chip" aria-hidden="true">2</span></label><label class="au-ask-user-question__option"><input type="radio" name="ex-resume" value="hold"><span class="au-ask-user-question__option-body"><span class="au-ask-user-question__option-title">Hold</span><span class="au-ask-user-question__option-desc">Wait for review</span></span><span class="au-ask-user-question__chip" aria-hidden="true">3</span></label><label class="au-ask-user-question__option"><input type="radio" name="ex-resume" value="split"><span class="au-ask-user-question__option-body"><span class="au-ask-user-question__option-title">Split rollout</span><span class="au-ask-user-question__option-desc">Stage then expand</span></span><span class="au-ask-user-question__chip" aria-hidden="true">4</span></label></fieldset><div class="au-ask-user-question__footer"><button class="au-btn au-btn--ghost au-btn--sm" type="submit" name="decision" value="skip">Skip</button><button class="au-btn au-btn--primary au-btn--sm" type="submit" name="decision" value="continue">Continue</button></div></form>

Pager

ask-user-question / Pagerinteractive

Code

ask-user-question.html + ask-user-question.css
ask-user-question
<style>
.au-ask-user-question {
  background: var(--au-surface);
  border: 1px solid var(--au-border-color);
  border-radius: var(--au-radius-xl);
  min-width: 0;
  padding: 16px 16px 12px;
}
.au-ask-user-question__eyebrow,
.au-ask-user-question__progress {
  color: var(--au-fg-muted);
  font: 400 12px/1.3 var(--au-font-sans);
  margin: 0 0 8px;
}
.au-ask-user-question__title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.35;
  margin: 0 0 8px;
}
.au-ask-user-question__options { border: 0; display: grid; gap: 2px; margin: 0; padding: 0; }
.au-ask-user-question__option {
  align-items: center;
  border-radius: var(--au-radius-lg);
  color: var(--au-fg);
  cursor: pointer;
  display: flex;
  gap: 8px;
  min-height: 40px;
  padding: 8px 12px;
}

@media (pointer: coarse) {
  .au-ask-user-question__option {
    min-height: 44px;
  }
}
.au-ask-user-question__option:hover { background: var(--au-surface-hover); }
.au-ask-user-question__option:has(input:checked) { background: var(--au-action-soft); }
.au-ask-user-question__option input { accent-color: var(--au-action); }
.au-ask-user-question__footer {
  align-items: center;
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 8px;
}
.au-ask-user-question__hint {
  color: var(--au-fg-subtle);
  font: 400 12px/1.4 var(--au-font-sans);
  margin-right: auto;
}
.au-ask-user-question[data-au-state="answered"] { opacity: .72; }
.au-ask-user-question[data-au-state="error"] { border-color: color-mix(in srgb, var(--au-danger) 45%, transparent); }

/* --- absorbed: multi/pager chrome --- */
/* agent-ui / approval-pager — first-class component (promoted from host extracts). */
/* 04 Multi-question approval pager */
.au-approval-pager { display: grid; gap: 12px; }
.au-approval-pager__nav {
  align-items: center;
  display: flex;
  gap: 8px;
  justify-content: space-between;
}
.au-approval-pager__dots { display: flex; gap: 8px; }
.au-approval-pager__dot {
  background: var(--au-surface-muted);
  border: 1px solid var(--au-border-color);
  border-radius: 50%;
  height: 8px;
  padding: 0;
  width: 8px;
}
@media (max-width: 640px) {
  .au-approval-pager__dot {
    height: 40px;
    min-width: 40px;
    width: 40px;
  }
}
.au-approval-pager__dot[aria-current="true"] {
  background: var(--au-action);
  border-color: var(--au-action);
}
.au-approval-pager__panel[hidden] { display: none; }
</style>

<div class="au-approval-pager" data-au-component="ask-user-question" data-au-variant="pager"><div class="au-approval-pager__nav"><button type="button" class="au-btn au-btn--ghost au-btn--sm" data-au-page-prev>Back</button><div class="au-approval-pager__dots"><button type="button" class="au-approval-pager__dot" aria-current="true" aria-label="Question 1"></button><button type="button" class="au-approval-pager__dot" aria-label="Question 2"></button></div><button type="button" class="au-btn au-btn--ghost au-btn--sm" data-au-page-next>Next</button></div></div>

Component contract

Install
tokens.css · ask-user-question.css · button.css
States
waiting, answered, error, cancelled
Host
validation, persistence, and plan resumption
For agents
ask-user-question.contract
# agent-ui / ask-user-question
component: ask-user-question
selector: .au-ask-user-question
data_au_component: ask-user-question
purpose: Bounded option question with optional multi/pager chrome (absorbs approval-pager).

install:
  - tokens.css
  - ask-user-question.css
  - button.css for actions

states: waiting, answered, error, cancelled.
css_variables: Uses semantic tokens.
events: native form, focus, and click only — no custom events or runtime required
no_javascript: Native form submits without script.
host_owns: The host owns validation, persistence, and plan resumption.
accessibility: Options need visible labels; progress as text.
security: Validate answers on the host before resuming work.

rules:
  - Host owns execution, authorization, persistence, validation, and state transitions.
  - Components render host-provided state; they never execute tools or imply approval.
  - Escape untrusted model output, tool args, and tool output before insertion.
  - Use only documented data-au-* attributes and data-au-state values.
  - Keep the no-JS path usable. Do not add React, Tailwind, bundlers, or remote assets.
source: components/ask-user-question/ask-user-question.{html,css} + README.md + fixture.html