Nº 526 of 528
Ask with a source and a model
Style sheet starts attached. Add source offers two more. Quill or Quill small. Send reports the model, the sources, and the count.
Preview
Use it
Free to use · credit appreciated1 Once, in your project
npx skills add SusanAcharya/Design-Lounge 2 Then ask
Using the Design Lounge skill, build "Ask with a source and a model" (piece prompt-source-model) in my stack. Match its brief; restyle it onto my product's theme.
No skill? Paste the brief instead. It carries the numbers, tokens and behaviour.
<!-- Design Lounge Nº 526 · "Ask with a source and a model" · www.designlounge.live -->
# Ask with a source and a model
> **Build brief for a coding agent.** Rebuild this piece in the reader's stack. If they haven't said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don't "improve" them. When a kit is locked, Send is `--primary` and a source chip uses `--primary-soft`. This demo uses the numbers below.
## What it is
The ask box on Quire, a Thursday note desk. It is not the tone box. That box is `prompt-composer`, and it has Plain, Short, and Formal. This one attaches a source and names the model. Style sheet starts on the box. Add source opens House rules and Night book. The model button reads Quill, and one click switches it to Quill small. Send stays off until the field has text that is not only space. Sending does not invent an answer. It prints the model, the attached names, and the trimmed count. A sourced paragraph that is already written is `cited-answer`. The whole thread is `ai-chat-workspace`.
## Reference behaviour
1. The field is empty. Placeholder: "Which line should lead the Thursday note?". Send is disabled. The status line is empty.
2. Style sheet is attached, with a remove control named "Remove Style sheet".
3. Add source is collapsed. Activating it opens a list: House rules, Night book.
4. Choosing a row removes it from the list, inserts a chip before Add source, and closes the list.
5. Removing a chip returns that name to the list and shows Add source if it was hidden.
6. Add source hides when the list is empty. It returns when a chip is removed.
7. The model button starts as Quill, `aria-pressed="false"`. One click sets Quill small and `aria-pressed="true"`. The next click returns to Quill.
8. Any non-space character enables Send. Clearing the field disables Send and clears the status.
9. Submit writes `Asked Quill · Style sheet · 12 characters`, using the current model name, the attached names in order separated by commas, and the trimmed length. No sources writes `no source` in that middle place.
10. A second edit, a model click, an add, or a remove clears the status until the next submit.
11. The field stops at 240 characters.
## Structure
```
form, 680px, padding 20px
label Ask
textarea, min-height 96px, maxlength 240
div.sources
span.src chips
button.add "Add source" aria-expanded aria-controls=menu
div.menu role=listbox, hidden until open
div.row
button.model
button.send, margin-left auto, 40px
p.out role=status, min-height 22px
```
… 126 more lines. Copy or download for the full brief. Loading the source…Brief
166 linesBuild brief for a coding agent. Rebuild this piece in the reader’s stack. If they haven’t said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don’t “improve” them. When a kit is locked, Send is
--primaryand a source chip uses--primary-soft. This demo uses the numbers below.
What it is
The ask box on Quire, a Thursday note desk. It is not the tone box. That box is prompt-composer, and it has Plain, Short, and Formal. This one attaches a source and names the model. Style sheet starts on the box. Add source opens House rules and Night book. The model button reads Quill, and one click switches it to Quill small. Send stays off until the field has text that is not only space. Sending does not invent an answer. It prints the model, the attached names, and the trimmed count. A sourced paragraph that is already written is cited-answer. The whole thread is ai-chat-workspace.
Reference behaviour
- The field is empty. Placeholder: “Which line should lead the Thursday note?”. Send is disabled. The status line is empty.
- Style sheet is attached, with a remove control named “Remove Style sheet”.
- Add source is collapsed. Activating it opens a list: House rules, Night book.
- Choosing a row removes it from the list, inserts a chip before Add source, and closes the list.
- Removing a chip returns that name to the list and shows Add source if it was hidden.
- Add source hides when the list is empty. It returns when a chip is removed.
- The model button starts as Quill,
aria-pressed="false". One click sets Quill small andaria-pressed="true". The next click returns to Quill. - Any non-space character enables Send. Clearing the field disables Send and clears the status.
- Submit writes
Asked Quill · Style sheet · 12 characters, using the current model name, the attached names in order separated by commas, and the trimmed length. No sources writesno sourcein that middle place. - A second edit, a model click, an add, or a remove clears the status until the next submit.
- The field stops at 240 characters.
Structure
form, 680px, padding 20px
label Ask
textarea, min-height 96px, maxlength 240
div.sources
span.src chips
button.add "Add source" aria-expanded aria-controls=menu
div.menu role=listbox, hidden until open
div.row
button.model
button.send, margin-left auto, 40px
p.out role=status, min-height 22px
- Source chips are not buttons. The remove control inside the chip is the button.
- Add source and the model are
type="button"so they do not submit. - Send is
type="submit". - The menu is
position: absoluteunder Add source, min-width 180px. It does not push the model row.
Tokens
:root {
--bg: #f4f1ea;
--surface: #fffdf8;
--ink: #1a1814;
--ink-2: #5c564c;
--line: #e3dcd0;
--line-2: #cfc6b6;
--ink-blue: #1e3a5f;
--soft: #e7eef6;
--serif: "Fraunces", Georgia, serif;
--sans: "Public Sans", system-ui, sans-serif;
--radius: 2px;
}
Chips, Add source, and the model button are pills (999px). The field, the menu, and Send use --radius.
Typography
| Role | Family | Size | Weight | Line | Tracking |
|---|---|---|---|---|---|
| Label | Public Sans | 13px | 500 | 1 | 0 |
| Field | Public Sans | 16px | 400 | 1.45 | 0 |
| Chip, Add, model | Public Sans | 13px | 500 | 1 | 0 |
| Menu row | Public Sans | 14px | 500 | 1 | 0 |
| Send | Public Sans | 14px | 600 | 1 | 0 |
| Status | Public Sans | 14px | 400 | 1.4 | 0 |
Fraunces is loaded for a locked editorial pairing that wants a serif question. This demo sets the label and the field in Public Sans. Do not set the field in the serif.
Motion
| Thing | Trigger | From | To | Duration | Reduced motion |
|---|---|---|---|---|---|
| Menu | Add source | hidden | shown | none | instant |
| Status | submit | empty | one line | none | instant |
No typewriter. The model name swaps in place.
States
- Send disabled: background
#e7e2d8, text#5c564c. Enabled: background#1e3a5f, text#f4f1ea. - Source chip: background
#e7eef6, border and text#1e3a5f, height 32px. - Model at rest: white, border
#cfc6b6, label Quill. - Model pressed: background
#1a1814, text#f4f1ea, label Quill small. - Menu row hover: background
#e7eef6. - Field focus: border
#1e3a5f. The browser outline is suppressed on the field because the border is the indicator. Every button keeps a 2px#1e3a5ffocus ring, offset 3px. - Add source hidden: the
hiddenattribute, notvisibility.
Accessibility
- The field has a real label, Ask. The placeholder is not the name.
- Add source has
aria-expandedandaria-controls. The menu isrole="listbox"named Sources. Each row isrole="option". - Remove buttons are named “Remove Style sheet”, “Remove House rules”, or “Remove Night book”. The icon is
aria-hidden. - The model button’s accessible name is its visible label, Quill or Quill small.
aria-pressedmatches Quill small. - Status is
role="status". - Focus order: field, remove buttons left to right, Add source, menu rows when open, model, Send.
- Send is disabled, so it is not in the tab order until the field has text.
- Contrast:
#1a1814on#fffdf8,#f4f1eaon#1e3a5f,#1e3a5fon#e7eef6. - Hit targets: Send is 40px. Chips and the model are 32px, which is the dense desk size. On a phone, make the model and Send 44px.
Responsive rules
- ≥1280: the form stays 680px, centred.
- 768: same form, page padding 24px. The menu stays 180px and may overlay the chips.
- <640: the form is
width: calc(100% - 32px). The model row wraps. Send stays on the right of its row, 40px tall. The menu is at least 180px and must not leave the form: if Add source is near the right edge, align the menu to the form’s left padding. - Do not turn this into
prompt-composerby adding tone chips. A product that needs a tone and a source uses this box and puts the tone in the sentence, or asks for one control, not both rows.
Acceptance checklist
Always
- A source can be attached before there is text, and Send stays disabled until there is text.
- Add source lists only names that are not already chips.
- Removing a chip returns that name to the list.
- The model is one button with two labels, not a second form.
- Submit prints the model, the sources, and the trimmed count. It does not write an answer.
- The field maxlength is 240.
- The menu does not push the Send row down.
This demo
- Style sheet is attached on the first frame.
- The list starts as House rules and Night book.
- Model labels are Quill and Quill small.
- Placeholder is “Which line should lead the Thursday note?”.
- An empty source list prints the words “no source” between the dots.
Implementation notes
Build the spare names from the menu, so the list and the script cannot drift:
const pool = [...menu.querySelectorAll('[data-name]')].map((b) => b.dataset.name);
On choose, splice that name out of pool, remove the option, and insert a chip before Add source. On remove, push the name back and append a new option. Hide Add source when pool is empty.
The status line is one template:
const via = names.length ? names.join(', ') : 'no source';
out.textContent = 'Asked ' + model.textContent + ' · ' + via + ' · ' + q.value.trim().length + ' characters';
Clear out on input, on model click, on add, and on remove.
Common mistakes:
- Reusing
prompt-composerand adding the model as a fourth tone. Tone and model are different jobs. - Letting Send invent a paragraph. This piece ends at the ask.
- A native file input. The sources are named documents already on the desk.
- Leaving the menu open after a choice, or leaving Add source visible when nothing remains.
Details
- Palette
- Type
- Fraunces · Public Sans
- Motion
- Static
- Build
- One session
- Tags