iOS Design Spec

# A conversation,
given no shape.

The ChatGPT iOS app, dissected. White canvas. One #10A37F green you almost never see. User on the right with a bubble, model on the left with nothing — just text and a single black mark.

View Design Tokens Explore Surfaces
9:41
History · Drawer
9:41
ChatGPT 4o ▾
How do I center a div in CSS without flexbox?

You have a few options. The simplest one for a single element:

css⧉ Copy
.parent {
display: grid;
place-items: center;
}
Message ChatGPT
Conversation
9:41
ChatGPT 4o
Help me plan
a relaxing day
Explain something
to a 6-year-old
Write a draft
resignation letter
Make a list
of weekend reads
Message ChatGPT
New Chat
iOS Surface Anatomy

## Three surfaces. No chrome.

Every ChatGPT screen earns its position by adding as little as possible — a white canvas, asymmetric bubble grammar, and a single black submit circle that quietly appears when there's text to send.

### Conversation

User messages live on the right inside a `#F4F4F4` bubble at `22px` radius. Assistant replies have no bubble at all — just left-aligned markdown next to a small black avatar. The asymmetry is the grammar.

### History Drawer

Sidebar lives on a `#F9F9F9` warm-gray. Today / Yesterday / Previous 7 Days as section labels — never UI cards, never tabs. The user row pins to the bottom with a tiny Plus badge.

### New Chat

Empty state is centered: black knot logo, model name, and 2×2 suggestion cards at `14px` radius. No hero copy, no marketing — just permission to start typing.

Voice Mode

### The whole screen becomes a microphone.

Tap the voice icon and the conversation collapses into a single breathing orb — a graphite sphere with subtle inner glow that scales with your speech amplitude. Three controls below: mute, dismiss, end. Everything else is stripped away.

The orb's animation honors iOS Reduce Motion: it switches to a flat opacity pulse instead of a scale-breathe when set.

`orb: 200×200pt` `shadow: y20 b60` `amplitude: 0–1.0` `fallback: opacity pulse`
Camera
Photos
Files
Scan Document
Vision Attach

### Anything iOS can see, ChatGPT can read.

Tap the + on the input bar and an iOS-native action sheet lifts up: Camera, Photos, Files, Scan Document. Attached media gets a 64×64 thumbnail above the input, with a tiny ✕ to remove.

Scan Document uses VisionKit's document camera — the same one Apple Notes uses — so the corner-detection and perspective-correction feel exactly like the system.

`UIDocumentCameraVC` `PHPicker` `UIImagePicker`
Model Picker

### One tap, the whole roster.

Tapping the "ChatGPT 4o ▾" header in the nav lifts a small floating sheet — not a full-screen modal. GPT-4o, GPT-4o mini, o1, o1 mini, each with a one-line use-case description. The currently selected model carries a single green check.

The sheet's corner radius is `14pt` matching iOS-native sheets; its shadow is softer to keep the focus on copy.

`sheet radius: 14pt` `row height: 56pt` `check: #10A37F`
GPT-4o
Newest and most advanced
GPT-4o mini
Faster for everyday tasks
o1
Best at reasoning
o1 mini
Faster reasoning
Design System Reference

## Almost no system. That is the system.

ChatGPT's iOS app reaches for fewer tokens than almost any consumer app in the App Store. One green you barely see. One bubble color. A handful of grays. The point is that nothing is in the way.

View Source ↗

### Color

White canvas. Bubble background is barely-there gray. The OpenAI green appears only on confirms, model checkmarks, and the tiniest active states. Every other "color" is a shade of ink.

Primary Brand
OpenAI Green
#10A37F
Green Hover
#0D8C6C
True Ink
#000000
Canvas
#ffffff
Dark Mode
#212121
Surfaces
Sidebar
#F9F9F9
User Bubble
#F4F4F4
Border Soft
#ECECEC
Border Strong
#D9D9D9
Code Block
#0D0D0D
Text
Primary
#000000
Soft Ink
#2F2F2F
Muted
#5D5D5D
Dim
#8E8E8E
Placeholder
#B4B4B4
Semantic
Negative
#E5484D
Warning
#F5A623
Announce
#4F46E5
Confirm Grad
extracted
Green Wash
rgba 10%

### Typography

Söhne family — substituted here with Inter. Conversational legibility over expression. Body sits at 16/1.5 for sustained reading. The model selector and section labels are the only places weight changes register.

Token | Sample | Size | Weight | Line
--- | --- | --- | --- | ---
--display-empty | What can I help with? | 26 / 1.63rem | 600 | 1.2
--model-title | ChatGPT 4o | 18 / 1.13rem | 600 | 1.2
--msg-body | A conversation that disappears so the answer doesn't. | 16 / 1.00rem | 400 | 1.5
--author-label | ChatGPT | 14 / 0.88rem | 600 | 1.3
--bubble-body | How do I center a div? | 15 / 0.94rem | 400 | 1.45
--code-mono | place-items: center; | 13 / 0.81rem | 400 | 1.5
--sidebar-section | Today | 11 / 0.69rem | 600 | 1.2
--account-pill | Plus | 10 / 0.63rem | 600 | 1.2
--input-placeholder | Message ChatGPT | 15 / 0.94rem | 400 | 1.4

### Radius

The user bubble's 22px corner is the most-seen radius in the app — bigger than the input pill, softer than any button. Buttons stay at 8px. The send button is a 50% black circle. Everything else hovers at 10–14px.

Minimal
2px
Item
6px
Button
8px
Code
10px
Card
14px
Bubble
22px
Input
24px
Send
50%

### iOS Spec Strip

The constants that anchor the iOS implementation across iPhone 12 mini through iPhone 16 Pro Max.

Bubble max-width
78%
User bubble caps at 78% of viewport so it never reaches the assistant side.
Avatar size
24×24pt
Small black knot. Sits 4pt above the message baseline.
Send circle
32×32pt
Fades from gray to black the instant the textarea has content.
Input radius
24pt
Grows in height as the textarea expands. Radius stays the same.
Side padding
14pt
12pt on the input bar; 16pt on the sidebar.
Sheet radius
14pt
All floating sheets (model picker, attach) share the same.
Sidebar width
82%
Drawer overlay; the 18% trailing edge dims to rgba(0,0,0,0.4).
Stream rate
~30 tok/s
Text streams character-by-character with a 1pt blinking cursor.

### Components

Buttons stay rectangular at 8px. The only true circle is the send. Inputs are pills. Tags are barely there.

##### Buttons

Send Upgrade to Plus Cancel Regenerate

##### Inputs

Default Plus o1

##### Bubble + Reply

How do I center a div?
Use `place-items: center` on the parent.
View source ↗