Skip to content

Commit 1fd86b1

Browse files
Jing-yilinclaude
andcommitted
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>
1 parent 8b3845e commit 1fd86b1

9 files changed

Lines changed: 1165 additions & 30 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ path and the two modal sheets.*
4747
have: the source composites it out, the iOS frame spec draws it, and this run
4848
keeps the frame and excludes the top 56pt from its numbers.*
4949

50-
### `notion-ios`, six screens
50+
### `notion-ios`, eighteen screens
5151

5252
[![notion-ios](assets/workflow/case-notion.webp)](mockups/canvases/notion-ios/README.md)
5353

‎RELEASE-NOTES.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ Everything below is on `main` and reaches no install until a version is cut.
2929
sixteen. Two tokens moved with the re-measurement: the sheet inset is 68
3030
rather than 71, and the type stack names SF Pro's Text cut outright, since
3131
`-apple-system` resolves to the Display cut and renders about 4% narrow.
32+
- **And three more: the Plus & Notion AI purchase sheet.** Monthly selected,
33+
yearly selected, and the StoreKit "You're all set" alert over the dimmed
34+
sheet with the subscribe button spinning. The sheet is Apple's paywall
35+
rather than one of the app's own, so its metrics sit in a board-local block
36+
after the shared tokens. The cat and the sparkle strokes on the feature card
37+
are the folder's first `artgen` assets: `gpt-image-2` redraws of the
38+
capture's crops, keyed and scored in `art-gen.json`.
3239

3340
## v1.1.1
3441

‎mockups/canvases/notion-ios/16-plan-plus-ai-monthly.html‎

Lines changed: 193 additions & 0 deletions
Large diffs are not rendered by default.

‎mockups/canvases/notion-ios/17-plan-plus-ai-yearly.html‎

Lines changed: 193 additions & 0 deletions
Large diffs are not rendered by default.

‎mockups/canvases/notion-ios/18-purchase-success.html‎

Lines changed: 208 additions & 0 deletions
Large diffs are not rendered by default.

‎mockups/canvases/notion-ios/README.md‎

Lines changed: 94 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Notion iOS, a worked example
22

33
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
55
screens, every colour and metric traced to a sample off the source capture.
66

77
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
1010
| file | what it is |
1111
|---|---|
1212
| `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. |
1414
| `01-splash` … `06-share-settings-sheet` | The screens. 393 × 852 pt frames on 478 × 980 artboards, fully self-contained. |
1515
| `07-manage-data-sources` … `10-to-do-list-table` | The *adding a new data source* flow, added later against four more captures. |
1616
| `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. |
1718
| `probes.json` | The measurements behind the tokens, replayable with `refkit batch probes.json --against <shots> --pt 3`. |
1819

1920
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
125126
faded subtitle remnant within five grey levels of the capture the whole way
126127
down.
127128

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+
128174
## How close it lands
129175

130176
Screens 7–15, each against its own capture cropped to `(0, 0, 1179, 2556)` and
131177
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:
133181

134182
| # | screen | whole frame | below the status bar |
135183
|---|---|---|---|
@@ -142,23 +190,30 @@ rendered with `refkit shoot --scale 3 --crop-phone`, so both sides are the same
142190
| 13 | Email typed | 5.28 | 1.99 |
143191
| 14 | Verification code | 5.08 | 1.77 |
144192
| 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 |
145196

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
147198
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
151204
is `refkit diff <render> <capture>`; the right is the same measure over
152205
`y >= 180px`, which is where the app's own content starts.
153206

154207
What is left below that band is glyph antialiasing and the two deltas named
155208
below. Board 10 is worst of the nine because it carries the most type and the
156209
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.
158213

159-
`refkit batch probes.json --against <shots> --pt 3` replays all 43 probes
160-
against the renders: **33 box probes at a mean |dw| of 0.41pt and |dh| of
161-
0.18**, and 4 colour probes at a mean Δmax of 1.8. Per screen:
214+
`refkit batch probes.json --against <shots> --pt 3` replays all 62 probes
215+
against the renders: **50 box probes at a mean |dw| of 0.38pt and |dh| of
216+
0.32**, and 4 colour probes at a mean Δmax of 1.8. Per screen:
162217

163218
| # | screen | box probes | mean \|dw\| | mean \|dh\| | worst |
164219
|---|---|---|---|---|---|
@@ -171,6 +226,9 @@ against the renders: **33 box probes at a mean |dw| of 0.41pt and |dh| of
171226
| 13 | Email typed | 1 | 0.00 | 0.00 | 0.0 |
172227
| 14 | Verification code | 4 | 0.07 | 0.00 | 0.3 |
173228
| 15 | Code typed | 1 | 0.00 | 0.00 | 0.0 |
229+
| 16 | Plan sheet, monthly | 13 | 0.35 | 0.65 | 3.6 |
230+
| 17 | Plan sheet, yearly | 16's probes, the other card selected | | | |
231+
| 18 | Purchase success | 4 | 0.22 | 0.42 | 1.0 |
174232

175233
Screen 7 carries the spread on its own, and all of it is `nav-title`: 4.7pt,
176234
the standing `--n-t-nav` delta described above. Drop that one probe and 7 reads
@@ -182,6 +240,13 @@ scan <capture> col 60 55 90 --pt 3` reads the same #D4D4D4 band on every one of
182240
them, which is also why `--n-sheet-top` moved to 68 with five captures behind
183241
it.
184242

243+
Screen 16 carries two of its own. `pw-cat` is 3.6pt short in height, the
244+
generated cat's hind leg, described above. `pw-price-selected` reads the
245+
selected card 1.7 taller on the capture than on the render, and about 1.3 of
246+
that is the resample: the capture's 2pt border, blown up from 2.24 to 3 px/pt,
247+
spreads a third of a point past each edge, and the probe's threshold of 235 is
248+
loose enough to count it. Everything else on the sheet is within half a point.
249+
185250
Two colour deltas are worth naming. `acc-cta`, the Continue button, reads
186251
`#2280DE` on capture a2 against the board's `--n-blue` of `#2784E0`, a Δmax of
187252
5 and the worst colour delta in the folder — the token was measured off the
@@ -218,7 +283,10 @@ locally, then add the row back:
218283
{ "file": "ref-12-add-an-account-email", "label": "Work email" },
219284
{ "file": "ref-13-add-an-account-email-filled", "label": "Email typed" },
220285
{ "file": "ref-14-add-an-account-code", "label": "Verification code" },
221-
{ "file": "ref-15-add-an-account-code-filled", "label": "Code typed" }
286+
{ "file": "ref-15-add-an-account-code-filled", "label": "Code typed" },
287+
{ "file": "ref-16-plan-plus-ai-monthly", "label": "Plan sheet, monthly" },
288+
{ "file": "ref-17-plan-plus-ai-yearly", "label": "Plan sheet, yearly" },
289+
{ "file": "ref-18-purchase-success", "label": "Purchase success" }
222290
] }
223291
```
224292

@@ -261,6 +329,20 @@ have file names instead of ids. All nine are exact matches:
261329
Those exports are 1179 × 2676 and carry a 120px Mobbin banner at the **bottom**.
262330
Crop to `(0, 0, 1179, 2556)` before measuring anything off them.
263331

332+
Screens 16–18 came in as three Mobbin captures supplied with the request, so
333+
they have neither an id nor an export file name. They are 881 × 2000 with a
334+
90px banner at the bottom: crop to `(0, 0, 881, 1910)`, which is 393 × 852 pt
335+
at **2.2417 px/pt**, and pass that as `--pt` to every `refkit` call. For
336+
`probes.json` they are resampled to 1179 × 2556 (`assets/refs/s1.png` to
337+
`s3.png`) so the whole file replays at `--pt 3`; the resample blurs an edge by
338+
about a third of a point, which is most of `pw-price-selected`'s height delta.
339+
340+
| # | screen | source |
341+
|---|---|---|
342+
| 16 | Plan sheet, monthly | supplied capture, `Plus & AI` tab, monthly selected |
343+
| 17 | Plan sheet, yearly | supplied capture, yearly selected |
344+
| 18 | Purchase success | supplied capture, the alert over 16 |
345+
264346
None of the captures shows a Dynamic Island; Mobbin shoots on a device without
265347
one. Every board in this repo draws one anyway, so the frame keeps it. That is
266348
this repo's framing, not a property of the app.

0 commit comments

Comments
 (0)