You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1fd86b1
Browse filesBrowse the repository at this point in the historyBrowse files
notion-ios: the purchase sheet is boards 16–18, built by gen.py
Main gained 07–15 and a generator while this branch was open, so the three
paywall boards move to the end of the row and their generator folds into
gen.py as a section after the account flow, sharing TOKENS and BASE with
the other eighteen. The scratch script that drew them is gone.
The status bar's ink was --n-text where the capture's is black, which is
why the battery's nub read 4pt short; the bar is #000 now, with the
outline and nub at .5 and .55. Nineteen probes for the sheet join
probes.json against the captures resampled to 3 px/pt, and the README's
"How close it lands" tables carry rows 16–18.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: mockups/canvases/notion-ios/README.md
+94-12Lines changed: 94 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
# Notion iOS, a worked example
2
2
3
3
A real run of the `clone-prototype` skill, kept as the reference for what a
4
-
finished board looks like. One measured token block plus fifteen replica
4
+
finished board looks like. One measured token block plus eighteen replica
5
5
screens, every colour and metric traced to a sample off the source capture.
6
6
7
7
Open it with `?canvas=notion-ios`, or a single board with
@@ -10,10 +10,11 @@ Open it with `?canvas=notion-ios`, or a single board with
10
10
| file | what it is |
11
11
|---|---|
12
12
|`gen.py`| The source of truth. Every `NN-*.html` here is its output; edit the generator and re-run, never the HTML. |
13
-
|`00-design-tokens.html`| The contract. Swatches, type ramp, radii, metrics, and the evidence for each value. Inlined byte-identically into all fifteen screens. |
13
+
|`00-design-tokens.html`| The contract. Swatches, type ramp, radii, metrics, and the evidence for each value. Inlined byte-identically into all eighteen screens. |
14
14
|`01-splash` … `06-share-settings-sheet`| The screens. 393 × 852 pt frames on 478 × 980 artboards, fully self-contained. |
15
15
|`07-manage-data-sources` … `10-to-do-list-table`| The *adding a new data source* flow, added later against four more captures. |
16
16
|`11-add-an-account` … `15-add-an-account-code-filled`| The *adding an account* flow, five states of one sheet, against five more captures. |
17
+
|`16-plan-plus-ai-monthly` … `18-purchase-success`| The *Plus & Notion AI purchase sheet*, Apple's paywall over the dimmed app, against three more captures. |
17
18
|`probes.json`| The measurements behind the tokens, replayable with `refkit batch probes.json --against <shots> --pt 3`. |
18
19
19
20
Two things in `00-design-tokens.html` are worth reading. The capture scale
@@ -125,11 +126,58 @@ alpha runs 0 to 1 over 17 to 52pt from the sheet's top edge, which puts the
125
126
faded subtitle remnant within five grey levels of the capture the whole way
126
127
down.
127
128
129
+
## The purchase sheet, 16 to 18
130
+
131
+
Three captures of the in-app Plus & AI paywall: the monthly price selected,
132
+
the yearly, and the monthly sheet dimmed under the StoreKit "You're all set"
133
+
alert with the subscribe button spinning. This is Apple's sheet rather than
134
+
one of the app's own, and almost nothing on it is a token:
135
+
136
+
-**The sheet sits at 58.9, not `--n-sheet-top`'s 68**, with a 38pt corner
137
+
and a 36 × 4.5 `#C4C4C4` grabber 5.3 below the edge. The app dims to
138
+
`#C6C6C6` behind it, and to `#9E9E9E` once the alert's scrim is on top.
139
+
-**The status bar is the stock 17pt one.** The shared block sets a 16px
140
+
clock 12pt lower, so the three boards carry their own bar: clock at 54,
141
+
cap top 22.8, and the signal, wifi and battery drawn to the capture's
142
+
19.7, 18.8 and 27.2 widths. The battery's outline and nub are black at
143
+
.5 and .55 over the grey, which is where `pw-status-icons` lands.
144
+
-**Four blues, none of them `--n-blue`.** The feature card's checks and
145
+
`Notion AI` are `#4E7AB0`; the selected price card is a 2pt `#487ED0`
146
+
border on `#E7F3FF`, its price `#467AB9`; the subscribe button is
147
+
`#4380D7`; the alert's OK pill is `#367CEF`.
148
+
- The segmented control's white pill has **no shadow**, and its label goes
149
+
from 400 to 600 when selected; the track is `#EBEBEB`, 31.7 tall, 1.8 inset.
150
+
- The feature card is **taller than its window**. It is 249.8 × 300 with a
151
+
three-layer shadow, drawn inside a 289.7 tall hero and clipped by a 40pt
152
+
linear fade to white. `refkit shoot --clip-ok div.hero` is what keeps the
153
+
overflow check quiet about it.
154
+
- While it spins, the subscribe button is **54.4 tall rather than 50.4**, and
155
+
the three links under it move 4pt down with it. The ring is 24pt, a 2.3
156
+
stroke, `#CFDCE8` with a `#2E3A36` arc.
157
+
- The alert is 318.7 × 152.2 at (37.3, 362.3) with a 30pt corner: white at
158
+
.7 over a 30px blur, an inset 1px white line at .6, and the title, body
159
+
and OK pill 29.5 in from its edge.
160
+
161
+
Text is placed by cap top throughout. `cap(size, lh)` in `gen.py` turns a
162
+
measured cap top into a CSS `top` for SF Pro, so a value in the generator is
163
+
the number read off the capture, not a number tuned until it looked right.
164
+
165
+
**The cat and the sparkles are generated, not cropped.** They are the
166
+
folder's first `artgen` assets: `gpt-image-2` redraws of the capture's crops
167
+
in `assets/art/`, keyed and shipped at 3× the measured box as `assets/cat.png`
168
+
and `assets/spark.png`. `art-gen.json` records the scores against the crop:
169
+
cat 13.97, sparkles 10.9, with a second independent return at 14.56 and 11.12
170
+
that did not beat the first. The one visible cost is the cat's hind leg, which
171
+
ends about 4pt higher than the capture's; `pw-cat` records it. A crop would
172
+
have scored 0, and the redraw was the brief.
173
+
128
174
## How close it lands
129
175
130
176
Screens 7–15, each against its own capture cropped to `(0, 0, 1179, 2556)` and
131
177
rendered with `refkit shoot --scale 3 --crop-phone`, so both sides are the same
132
-
393 × 852 pt screen at 3 px/pt. Mean absolute delta in levels of 255:
178
+
393 × 852 pt screen at 3 px/pt. Screens 16–18 the same way, except that their
179
+
captures are 2.2417 px/pt, so the render is resampled down to the capture
180
+
rather than the capture up. Mean absolute delta in levels of 255:
133
181
134
182
| # | screen | whole frame | below the status bar |
135
183
|---|---|---|---|
@@ -142,23 +190,30 @@ rendered with `refkit shoot --scale 3 --crop-phone`, so both sides are the same
142
190
| 13 | Email typed | 5.28 | 1.99 |
143
191
| 14 | Verification code | 5.08 | 1.77 |
144
192
| 15 | Code typed | 5.07 | 1.77 |
193
+
| 16 | Plan sheet, monthly | 5.02 | 2.61 |
194
+
| 17 | Plan sheet, yearly | 5.23 | 2.83 |
195
+
| 18 | Purchase success | 4.27 | 2.26 |
145
196
146
-
**Whole-frame mean 5.37, worst 6.55. Below the status bar, mean 1.94, worst
197
+
**Whole-frame mean 5.17, worst 6.55. Below the status bar, mean 2.10, worst
147
198
2.84.** The gap between the two columns is one thing, and it is this repo's
148
-
framing rather than a miss: the top 60pt band scores 51.9 on eight of the nine
149
-
boards and 59.2 on board 10, near enough to a constant, because every board
150
-
here draws a Dynamic Island and none of the captures has one. The left column
199
+
framing rather than a miss: the top 60pt band scores 51.9 on eight of the first
200
+
nine boards and 59.2 on board 10, near enough to a constant, because every
201
+
board here draws a Dynamic Island and none of the captures has one. On 16–18
202
+
the same band reads 37.0, 37.0 and 30.8, lower only because the island sits on
203
+
a dimmed grey rather than white. The left column
151
204
is `refkit diff <render> <capture>`; the right is the same measure over
152
205
`y >= 180px`, which is where the app's own content starts.
153
206
154
207
What is left below that band is glyph antialiasing and the two deltas named
155
208
below. Board 10 is worst of the nine because it carries the most type and the
156
209
only clipped table; board 11 is best because it is a sheet of six outlined
157
-
buttons on a flat ground.
210
+
buttons on a flat ground. The purchase sheet's three sit higher below the bar
211
+
than the account flow's because their captures are softer, 2.24 px/pt against
212
+
3, so every glyph edge disagrees by a little more.
0 commit comments