← All screens

Dialog catalog — what the desk can render.

Every rich element that can land inline in a chat thread. Tier A (1.0 native) covers the full set; tier B is bigger surfaces like spreadsheet/kanban that ship later. Five representative renders below show the interaction language.

Coverage map

26 elements · Tier A: 22 · Tier B: 4

Pickers

date
{ value: ISO8601, min?, max?, disabled?[] }
A
date-range
{ start, end, maxSpan? }
A
time
{ value: HH:MM, step?: 15|30 }
A
datetime
{ value: ISO8601, tz? }
A
calendar
{ month, view: m|w|d, events[] }
A
availability-grid view ↓
{ slots[][], tz, duration, picked? }
Arendered
number
{ value, min?, max?, step? }
A
currency
{ value, currency: ISO4217 }
A
duration
{ value: seconds }
A
file
{ accept[], multiple, source: local|cloud|camera }
A
contact view ↓
{ source: AddressBook, multi?, allowNew? }
Arendered
folder-as-tree
{ root, lazyChildren: true }
A
location view ↓
{ lat, lng, label?, results[]? }
Arendered
color
{ value: oklch|hex, swatches?[] }
A
tag allowNew
{ chips[], suggestions[], allowNew }
A
rating
{ value: 0-5|NPS, scale }
A
otp
{ length: 4|6, channel: sms|app }
A

Drafts (review · edit · accept · reject)

email-draft ·rendered in chat
{ to[], cc?, subject, body, attachments[] }
Alive
imessage-draft
{ to: handle, body, replyTo? }
A
slack-draft
{ channel, thread?, body, mentions[] }
A
calendar-invite
{ title, when, attendees[], location, notes? }
A
approval-with-comment
{ wraps: any-draft, comment? }
A

Capture (camera, voice, signature)

voice-record ·rendered in chat
{ duration, waveform[], trim?, transcript? }
Alive
video-clip
{ duration, thumbnail, trim? }
A
camera
{ aspect?, lens?: wide|tele, framing? }
A
qr-scan
{ formats: [qr, code128, ean…], onDecode }
A
biometric
{ reason, fallback: passcode }
A
signature view ↓
{ strokes[][], svg, signedAt }
Arendered
image-annotation
{ image, marks[]: rect|arrow|comment }
A
pdf-annotation
{ doc, marks[]: highlight|comment }
A
drawing-canvas
{ strokes[][], tool: pen|highlight|erase }
A

Displays (read-mostly, picked-from)

table
{ columns[], rows[][], sort?, filter? }
A
chart
{ type: line|bar|pie|sankey, data }
A
map-display
{ tiles, route?, markers[] }
A
diff-viewer
{ before, after, mode: unified|split }
A
info-cards
variants: email · cal · pr · linear · msg · weather · ticker
A
card-carousel
{ cards[], select: single, swipe }
A
comparison-table view ↓
{ rows: attr[], columns: option[], pickable }
Arendered

Tier B · later

spreadsheet
{ cells, diff-edits, formulas? }
B
kanban
{ columns, cards, drag-drop }
B
pr-review
{ files[], hunks, approve-each }
B
live-dashboard-tile
{ source: stream, refresh, viz }
B

Representative renderings

Five elements detailed below cover the visual range: a grid-based picker, a list-based picker, a comparison surface, a freehand capture, and a deferred-from-3a passkey companion sheet. Other elements follow these patterns.

01

Availability grid

Pick a 30-min slot from the agent's open window. Calendly-style; 5 weekdays × 12 half-hours; tapped slot is the answer.

9:41
Chat Yemaya · Board Prep Cancel
Ye Yemaya · agent
When works for the AGM rehearsal? I have these open — 30 min each.
Availability · 30 min · CET
Mon13
Tue14
Wed15
Thu16
Fri17
09:00
09:30
10:00
10:30
11:00
11:30
12:00
14:00
14:30
15:00
Picked: Thu 16 · 11:30 → Lisa, Anna
Tap targets26px slots with 2px gaps clear 44pt finger zone via padding hit area. Diagonal swipe = range.
Density5 weekdays × 12 half-hours fits on a 320pt screen with 32pt time gutter. Vertical scroll for full day.
02

Contact picker

Native Address Book + Front Desk's known people. Multi-select with chips at the top; allowNew lets the user type a fresh email inline.

9:41
Draft Add recipients Done
Lisa Berg Anna Berg
Suggested · this thread
LB
Lisa Berg
lisa@yemaya.io
AB
Anna Berg
anna.berg@nordea.fi
Contacts · matching "li"
LC
Li Chen · v6 fund
li@accelfund.vc
LM
Liam McKenna
liam@saltandshade.co
LP
Linda Park
linda.park@gmail.com
Add as email
li
type a full email to add
SuggestedThread-aware — Lisa & Anna appear first because they're on this Yemaya conv. Smart default.
allowNewBottom row turns the live query into an email recipient. No "add contact" dialog — it's just a chip.
03

Comparison table

Rows = attributes, columns = options. Best-cell highlighting + pick-one CTA per column. Renders inline in the chat thread.

9:41
Chat Salt & Shade · Ops
SS Salt & Shade · agent
Three caterers replied. Here's the side-by-side — middle one's the value pick, third is the locked-in favorite from last year.
Bord
SE-117
Hjort
SE-115
Stora
SE-114
Per head
€68
€54
€81
Setup
+€280
incl.
+€120
Dietary
3 / 5
5 / 5
5 / 5
Won prior
2× last yr
Available 14 May
yes
yes
conflict
Tap Choose to draft the confirm email — or ask to refine the rubric.
Best cellAccent fill on the column with the most wins, value-style highlight per row. Reads even on glance.
Per-column CTA"Choose" is the cell's primary verb — no separate radio + submit pattern.
04

Signature

Freehand capture. Stored as SVG paths + raster fallback. Used for covenant amendments, NDA acceptance, delivery proof.

9:41
Doc Sign covenant · v6
Ye Yemaya · agent
Anna needs your signature on the covenant amendment. One page, redlines accepted. Sign below.
Signature · Jonas Lund
Stored as SVG · 12 strokes 2026-05-13 · 14:23 CET
SVG-first12 strokes captured as Bézier paths. Raster fallback in .png for non-SVG consumers.
Stroke widthThree weights — fine / medium / bold. Pressure-aware on supported Pencil/Apple Pencil hardware.
05

Location picker

Map + draggable pin + search-suggested results. Result rows are also tappable. Pin drops anywhere; selected row syncs pin.

9:41
Invite Location Done
Hjort · Skånegatan 80
Hjort
Skånegatan 80 · 116 35 Stockholm
0.8 km
Stora · Östermalm
Storgatan 1 · 114 51 Stockholm
1.4 km
Bord · SoFo
Bondegatan 48 · 116 33 Stockholm
0.6 km
SyncSelected result re-centers the pin and drops a bubble. Drag the pin to override; the search bar updates.
DistanceComputed from current location only with permission. Otherwise the column drops.
06

Passkey · cross-device QR

Deferred from drop 3a: caBLE QR sheet for signing in from a device that doesn't yet have a passkey. Scan with phone, biometric on phone, sign-in completes on the other device.

9:41
Sign-in Use another device
FD
Scan with your phone
Open the camera. Your passkey lives on the phone — biometric there signs you in here.
Bluetooth tunnel · 4:22 left
TunnelcaBLE v2 over Bluetooth — devices don't need to be paired; QR carries the handshake.
FallbacksIf no phone is handy → security key or one-time email link. Never a password.
Coverage 22 Tier-A elements · 5 detailed renderings · all schemas codified Pattern chat-thread inline rendering · same chrome as chat-mobile-ios Out of scope Tier B (spreadsheet, kanban, pr-review, live-dashboard-tile) — separate later drop