Repository navigation
canvases: apple-app-store, nine iOS 26 App Store screens with the template's status bar - #69
Conversation
…ate's status bar Nine native iPhone 16 Pro captures (1206 x 2622, a 402pt frame) rebuilt as one gen.py: a token board and two evidence boards for 80 tokens, the nine replicas, and the capture of each underneath. App icons are the originals from the iTunes lookup API; editorial art is a crop at its measured box. The status bar is templates/gen.py's byte for byte, moved +6pt as a group for the wider frame. clone-prototype's SKILL.md now says the capture's own glyphs (an iOS 26 battery, no-service bars) stay the template's too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LDu5gJ4DgBaidcAGHS7Dpy
refkit shoot --check-overflow found all three Foundations boards clipped, by 672, 122 and 452 px. Type moves to its own board, and evidence pages fill to a height rather than a fixed 40 rows, since the rows wrap. Five boards now where there were three, and every board fits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LDu5gJ4DgBaidcAGHS7Dpy
Deploying super-prototyping with
|
| Latest commit: |
c69a30e
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c9059846.super-prototyping.pages.dev |
| Branch Preview URL: | https://canvas-app-store-ios.super-prototyping.pages.dev |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d1a98d074a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -0,0 +1,114 @@ | |||
| { | |||
| "name": "App Store", | |||
There was a problem hiding this comment.
Commit the required canvas icon
A repo-wide git ls-tree check confirms this new canvas has no mockups/canvases/app-store-ios/icon.png, so its canvas welcome card is rendered without an app icon and the folder violates the required canvas artifact set. Add the App Store icon alongside this layout.
AGENTS.md reference: AGENTS.md:L48-L49
Useful? React with 👍 / 👎.
| refs = [{"file": "ref-" + s, "label": l} | ||
| for s, l, _ in SCREENS if "ref-" + s in names] |
There was a problem hiding this comment.
Keep layout generation stable without captures
On a fresh checkout, the intentionally ignored assets/refs/ files are absent, so this condition omits every reference entry and rewrites the committed three-row layout.json as a two-row file when the documented generator command runs. I reproduced this from an archive of the reviewed commit: all HTML stayed byte-identical, but layout.json changed from 2,363 to 1,415 bytes, leaving the worktree dirty after the mandatory regeneration workflow; commit the fresh-clone layout or otherwise make generation independent of ignored inputs.
AGENTS.md reference: AGENTS.md:L46-L49
Useful? React with 👍 / 👎.
| PERSON = ('<svg viewBox="0 0 18.3 19.3"><circle cx="9.15" cy="5.4" r="5.4"/>' | ||
| '<path d="M9.15 11.6C4.1 11.6 0 14.9 0 17.9c0 1 .5 1.4 1.6 1.4h15.1' | ||
| 'c1.1 0 1.6-.4 1.6-1.4 0-3-4.1-6.3-9.15-6.3Z"/></svg>') |
There was a problem hiding this comment.
Store custom SVGs in the asset tree
When the inspector encounters this account glyph (and similarly CHEV and SB_PERSON), it has no matching assets/icons/*.svg geometry because the folder contains only assets/art/ and ICON_DIR is unused. Consequently these literal SVGs cannot be named or handed back as vector assets; store the custom glyphs under assets/icons/ and inline those files through the generator.
AGENTS.md reference: AGENTS.md:L54-L58
Useful? React with 👍 / 👎.
A crop of interface scores well and cannot be edited, so everything the App Store draws is now HTML, CSS and traced SVG: type, pills, badges, chips, tab glyphs, sheet marks, the keyboard and p1's illustration. Every app icon is the iTunes original, including the five set on artwork. The Arcade logo is SF's U+F8FF outline. What stays a crop is the picture under the interface. crops.json gains an `erase` list, and cut() inpaints the listed icons, pills and type out with a harmonic fill before the board draws them again live. The 10-12 pt peeks stay whole, because they show too little to name an app. Mean delta goes from 2.32-8.00 to 3.62-8.02, and the READMEs say why. SKILL.md and references/assets.md now carry the rule and the erase traps. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LDu5gJ4DgBaidcAGHS7Dpy
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 22d8e1e2c1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| The one thing that changes is the frame. On a wider frame, move the | ||
| `SB_ICONS` group by the width delta so the battery keeps its right inset. |
There was a problem hiding this comment.
Define a group before telling clones to move it
For any clone whose phone is wider than 393px, this instruction has no object to move: mockups/canvases/templates/gen.py:176-179 inserts SB_ICONS directly into .sb, with no wrapper, while the preceding instruction requires statusbar() and SB_ICONS to remain unchanged. The 402px example works only because app-store-ios/gen.py:261-262,303-306 adds a new .glyphs wrapper, so an agent following the shipped skill literally either leaves the icons at their 393px positions or violates the recipe. Add the wrapper to the template or document the required modification.
AGENTS.md reference: AGENTS.md:L8-L12
Useful? React with 👍 / 👎.
| native screenshots (1206 × 2622, 3×, so a 402 × 874 pt frame). 23 boards in | ||
| three rows: a token board, a type board and three evidence boards for 80 | ||
| tokens, the nine replicas, and the capture of each column-for-column |
There was a problem hiding this comment.
Update the stale board and token counts
The generator now contains 102 token entries and emits four evidence boards, so it produces 15 boards without captures and 24 when all nine references exist; this README still reports 80 tokens, three evidence boards, and 23 total boards, and later claims a fresh clone has 14. The repository overview repeats the same stale figures, making this worked example's documented evidence inventory disagree with its committed generator and outputs.
AGENTS.md reference: AGENTS.md:L65-L66
Useful? React with 👍 / 👎.
p7-hero was cut at y 383, the top of the headline, which sliced the picture through the player's legs. The photograph actually fades to #000000 at 424, so the crop now ends there and erases the headline's first line out of the fade, and the CSS ramp that stood in for the missing 45 pt is gone. What the headline covered is filled from EA's published key art. A crop's new `guide` names the file, its URL and the affine from page pt that registers it (SIFT + RANSAC, median 0.14 px on the player). cut() fills the erased pixels from the log ratio of capture to guide, so the App Store's grade and fade come through. Only inside `boxes`: the App Store cut recomposes the skyline, logo and NFLPA badge, and the badge would show under "No". Arcade reads 4.21, was 4.88. The skill documents the guide and ending a crop at the picture's fade. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LDu5gJ4DgBaidcAGHS7Dpy
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2a0ebed69c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -0,0 +1,118 @@ | |||
| { | |||
| "name": "App Store", | |||
There was a problem hiding this comment.
Set the cover crop to the 402×874 phone
On the welcome page, this canvas falls back to the [46, 24, 393, 852] crop in CanvasLinkShapeUtil.tsx:99-103, but gen.py centers its 402×874 phone at [38, 24, 402, 874]. The resulting card starts 8 px inside the phone and ends at y=876 instead of y=898, visibly cutting off the sides and bottom—including the home-indicator area. Declare the matching coverBox in this layout.
AGENTS.md reference: AGENTS.md:L38-L40
Useful? React with 👍 / 👎.
The folder is one of Apple's own apps, so the welcome page's second row is where it belongs, and the slug is what puts it there: the row predicate reads `apple-`, and slug order inside the row puts App Store at the head of it. No shipped code has to learn a data slug by name. Its page name now keeps the convention every other folder keeps, "(example) App Store", and its card is Search rather than the first board that is not a `00-` sheet. The App Store icon it wears was apple-icons', borrowed because this folder had none. A sheet of 43 icons should not wear one app's face, so it gets four of its own in a 2x2 instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b188a5d8d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| The one thing that changes is the frame. On a wider frame, move the | ||
| `SB_ICONS` group by the width delta so the battery keeps its right inset. |
There was a problem hiding this comment.
Reconcile the status-icon shift with the worked example
For wider iPhones, this prescribes shifting by the full width delta, but the worked generator expands the frame from 393 to 402 pt while moving .glyphs only 6 pt (apple-app-store/gen.py:262-271) to match the measured battery edge. Following this shipped instruction would instead move the icons 9 pt and place the entire cluster 3 pt too far right; instruct agents to preserve the measured device inset or explicitly document the example's 6 pt shift.
AGENTS.md reference: AGENTS.md:L8-L12
Useful? React with 👍 / 👎.
| tmp = ART_DIR / ("." + slug + ".tmp.png") | ||
| subprocess.run(["curl", "-sL", url, "-o", str(tmp)], check=True) |
There was a problem hiding this comment.
Keep icon download temporaries in scratch
When adding or rebuilding an app icon, the download is written to assets/art/.<slug>.tmp.png, but it is unlinked only after PIL successfully decodes, resizes, and saves it. An interrupted run or malformed response therefore leaves a non-ignored transient inside the committed asset tree and dirties the worktree; place this temporary under the canvas's scratch/ directory and clean it on failure.
AGENTS.md reference: AGENTS.md:L63-L64
Useful? React with 👍 / 👎.
A glyph traced off a capture is one path of hundreds of implicit linetos, and at the size the tab bar and the search field show them the ragged edge is visible. Redraw them the way they were designed instead. Six are constructions: the magnifier and tab-search are a circle and a round-capped bar, the mic a stadium over a U-cradle, tab-today a rounded frame, tab-apps and tab-arcade a rounded square under rotate(45) and a vertical squash. Write the construction with its dimensions as parameters and fit the parameters against the trace at 16x. The rocket has no construction, so fit its outline: corners by turning angle, then a line, arc or Bezier per run. 18280 bytes of point soup down to 4936, ink boxes byte-identical so nothing moves, and 0.6% to 2.5% of the ink disagreeing with the trace -- the trace's own ragged edge, sub-pixel at 24 px. The 45 degree bar is worth a note: it traces about sqrt(2) thicker than its true stroke, so the redraw gives the magnifier's ring and handle one weight rather than copying the trace. redraw/ holds the two scripts and what they found. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fd9b02d5c9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return page(NAME + " - " + label, | ||
| '<div class="phone"%s>%s%s<div class="dim"></div>%s%s%s%s</div>' | ||
| % (' style="background:%s"' % ground if ground else "", | ||
| statusbar(), behind, back, sheet(top, body), above, home()), |
There was a problem hiding this comment.
Raise the sheet home indicator above the sheet
On every board built through sheet_screen() (01, 02, 04, and 09), home() remains at .home's z-index 6 while the opaque, bottom-reaching .sheet is z-index 8 (and the alert's second scrim is z-index 9). The indicator is therefore completely covered on these screens even though the frame is intended to draw it consistently; render it inside the sheet or above all sheet overlays.
Useful? React with 👍 / 👎.
The second row is "Apple's own apps, and the empty folder to copy", and apple-icons sat fourth in it purely by alphabet. It is two reference sheets of system icons, not an app someone opens to read a screen, so it belongs at the end next to templates rather than between Home & Lock Screen and Photos. `order` 1 and 2, which moves them in the page menu too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Tracing a glyph off a capture gives the right shape and the wrong object: one path of hundreds of implicit linetos, whose edges are visibly faceted at 2x while every delta reads 0, because a mean delta cannot see faceting that stays inside a pixel. The App Store run redrew the seven glyphs its boards draw large, and the method generalises, so it belongs in the skill rather than in that folder. Two halves, and only one of them is general. Which glyph gets which is the first decision: most interface glyphs are a composition of primitives, because that is how they were drawn, and a few are a shape with no construction to recover. - A construction is per-glyph authoring, so it stays a canvas folder's script: write the drawing with its dimensions as parameters and fit the parameters against the trace. references/glyphs.md has the loop, the reading and overlaying that find what the glyph actually is, and where to stop. - Fitting a contour is the same code every time, so it ships: `refkit refit` resamples, smooths, finds the corners by turning angle, and fits each run as a line, an arc or a cubic, keeping the file's viewBox byte-identical. It reproduces apple-app-store's rocket byte for byte, so redraw/refit.py goes. Also two pitfalls, both of which cost time here: shipping a trace a board draws large, and measuring a stroke off a diagonal edge, where a 45 degree bar traces about sqrt(2) thicker than it is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d056a512cb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| def _tangent(pts, i, ahead, k=6): | ||
| n = len(pts) | ||
| v = pts[(i + k) % n] - pts[i] if ahead else pts[i] - pts[(i - k) % n] |
There was a problem hiding this comment.
Reverse the end tangent before fitting cubics
For any contour segment that reaches the cubic fitter, _tangent(..., ahead=False) returns the forward arrival vector pts[i] - pts[i-k], but _fit_bezier constructs the second control point as p[-1] + alpha * t1. This places the handle beyond the endpoint rather than behind it, so non-line/non-circle glyphs repeatedly split or terminate at the depth cap with an incorrect end tangent and potentially a visible cusp. Reverse this vector or subtract it when constructing the control point.
Useful? React with 👍 / 👎.
| for raw in _contours(d): | ||
| notes.append("-- contour %d, %d traced points" % (len(parts) + 1, len(raw))) | ||
| parts.append(_contour_path(raw, notes, o)) | ||
| return head + '\n<path fill-rule="evenodd" d="%s"/>\n</svg>\n' % "".join(parts), notes |
There was a problem hiding this comment.
Preserve path styling when rewriting SVGs
When a traced SVG stores its color on the <path>—as several of the new assets/icons/*.svg files do—this replacement discards all original path attributes and emits only fill-rule. For example, applying the documented refkit refit --write flow to mark-account.svg drops its fill="#1C95FF"; because the root <svg> has no fill, the glyph silently becomes black. Preserve the original path's presentation attributes while replacing only its d value.
Useful? React with 👍 / 👎.
The pass that cursor/plugins ships as the unslop skill, run by Fable 5.1 over the four files d056a51 touched under skills/clone-prototype. Rewriting only, no claim added or dropped, and every measured number is the same digit for digit. What it caught, mostly: em dashes and mid-sentence colons standing in for a full stop, compressed fragments with the article and the verb missing ("is six and one", "The loop that fits it:", "2382 bytes and no curves in"), and figures of speech where the literal phrase is shorter ("pay for themselves", "the shape starts to go", "point soup"). "Primitive" stays: here it means a circle or a bar, which is the word for the thing rather than a metaphor. Two fixes beyond the rewrite: the blank lines between the new pitfalls bullets made that list render loose, and its 45deg/sqrt(2)/2x now match the °/√/× spelling the rest of the references use. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
apple-icons at 1 and templates at 2 moved both folders behind the alphabet, and the test asserted that everything after snapaction-ios was in slug order, so it failed on the change that was the point. Sort the tail by the rule readCanvasLibrary implements -- `order` first, slug to break the tie -- instead of naming the folders that declare one. A fourth folder can now declare an order without editing this test. The two that are last on the welcome page are still named, because that placement is a decision rather than a consequence. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c69a30ecd1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
|
|
||
| def compare(name: str, p, target, w, h): | ||
| OUT.mkdir(exist_ok=True) |
There was a problem hiding this comment.
Create the scratch parent before writing comparisons
On a fresh checkout, the ignored scratch/ directory does not exist, so every documented design.py invocation reaches OUT.mkdir(exist_ok=True) and raises FileNotFoundError while trying to create scratch/compare without its parent; because compare() runs before the --write block, even the regeneration command cannot update an SVG. Create the directory with parents=True so the committed redraw workflow works from a clean clone.
AGENTS.md reference: AGENTS.md:L63-L64
Useful? React with 👍 / 👎.
| # Last card on the welcome page, after apple-icons at 1: the folder you copy is | ||
| # not an example anyone came to look at. | ||
| "order": 2, |
There was a problem hiding this comment.
Remove the example-only order from the copied template
When a user follows the standard workflow and copies templates to start a real canvas, regenerating it preserves order: 2, so the new canvas is sorted behind every normal order-0 canvas instead of participating in slug order. This value only serves the repository's special Templates welcome card, as the adjacent comment states; omit it from the generator or ensure the copy workflow removes it.
AGENTS.md reference: AGENTS.md:L38-L42
Useful? React with 👍 / 👎.
Summary
Nine screens of the iOS 26 App Store as one canvas,
mockups/canvases/apple-app-store/, rebuilt from nine native iPhone 16 Pro screenshots (1206 × 2622, a 402 × 874 pt frame) theclone-prototypeway. Onegen.pybuilds 23 boards: a token board, a type board and three evidence boards for the measured tokens, the nine replicas, and the capture of each underneath.assets/icons/. The Arcade logo is SF's own U+F8FF outline.icons.json), masked to the superellipse. That includes the icons set on artwork (ABC News, Disney Solitaire, Procreate, Meowdoku and Royal Match), which used to be part of a crop.crops.json): the Today cards, the Games, Apps and Arcade heroes, and the Browse tiles. Any interface set over a picture is listed in the crop'seraseand inpainted out bycut(), then drawn again live on top. That covers lockups, headlines, pills, the Ad badge, the Browse labels and the Arcade wordmark. The exception is the 10–12 pt peeks at the scroll edge, which are too small to identify an app, so they stay whole crops.#000000. The headline's first line is erased out of it, and the fill under it comes from EA's published key art (4858 × 2732). That art is registered to the capture at a median 0.14 px on the player, andcut()downloads it intoassets/refs/. Only the player agrees with the capture, since the App Store cut moves the skyline, logo and badge. So the key art only guides the fill, inside[86, 356, 402, 424].templates/gen.py's, byte for byte, with its 9:41 clock. It is moved +6 pt as a group for the 402 pt frame. Nothing from the captures' own status bars is carried over.skills/clone-prototype/SKILL.mdandreferences/assets.mdnow say both things: take the status bar from the template, and crop only the picture while rebuilding the interface on it.assets.mdalso documents theeraselist and three traps it hit.Mean absolute delta against the captures, whole phone crop, in levels of 255:
With the interface still cropped and the captures' status-bar extras kept, these read 2.32–8.00. A crop scores 0 by construction, so the higher numbers are the price of boards whose interface can be edited, and that price is paid on purpose. The rest is by design: the frame draws a Dynamic Island and home indicator that screenshots leave out, and the template's tab-bar blur is heavier than iOS 26's glass.
The 23 lines of live type set over pictures on Apps, Games, Today, Search and Arcade land within 0.67 pt of the captures' ink, most of them exactly.
Checks
python3 gen.pytwice, byte-identical output.refkit tokens .passes: one shared:root, everyvar()and evidence row defined.refkit shoot --check-overflow: all nine replicas and the foundation boards fit.refkit batch probes.json: 15 colour probes replay at a mean Δ of 0.2, worst 2.The nine
ref-*capture boards andassets/refs/are gitignored, so the preview shows the 14 committed boards without the captures row.Preview: https://canvas-app-store-ios.super-prototyping.pages.dev/?canvas=apple-app-store
🤖 Generated with Claude Code
https://claude.ai/code/session_01LDu5gJ4DgBaidcAGHS7Dpy