Part 14 ended with two new entries in the consumer app's memory index, both notes about new design work. This post is that work.
At 14:28 the developer sent one message with two Figma links:
"Reuse token from [the design system file] To optimise the design for iPhone Duo and put it here [a new, empty file]"
The first file is a full code-to-Figma conversion of the consumer app. It holds five variable collections, the text styles and 97 screen frames at 390×844. The second file was empty.
A device newer than the model
iPhone Duo is Apple's book-style foldable. Apple's design guidelines page for it is dated 9 September 2026 and the phone goes on sale on 23 October. The model's training data ends in June, so anything it "remembered" about the device would have been a guess.
In the first three minutes the agent ran three web searches and fetched four pages: Apple's spec page, Apple's developer tech talk, Wikipedia and a designer's write-up. It also saved two Apple pages to its scratch folder as raw markdown: the Human Interface Guidelines page "Designing for iPhone Duo", and the developer article on preparing apps for the device. Every rule it applied later was quoted from those copies.
What it found:
- Apple publishes pixels, not points. The outer display is 1398×2034 at 460 ppi (5.4"). The inner display is 1878×2670 at 430 ppi (7.6"), and it sits in landscape when the phone is open. The agent divided by three to get 466×678 and 890×626 points. Those numbers are derived, and one third-party site gives different ones (669×951, worked out from App Store screenshot sizes). The design file says "derived" everywhere the numbers appear.
- Controls move to the side. On the outer display, and on the inner display in landscape, "the Dynamic Island, the status bar, the toolbar (including navigation buttons), and the tab bar" stack down the trailing edge. Back or Close goes at the top of that column. Buttons with text labels stay in horizontal bars.
- The fold only counts when the phone is partly folded. Then it is a "reserved region" that content stays clear of. When the phone lies flat, it is just the middle of the screen. In grids, the guidelines prefer "an even number of columns so content divides cleanly".
- Size classes, not devices. "A compact width layout for the outer display and a regular width layout for the inner display give you the fundamentals for every pose."
- The diagrams were out of reach. Every image on the guidelines page returned 403 or 404, so the agent never saw Apple's drawings of the side rail. The rail's proportions are its own, and the file labels them that way.
One question
Need Help Implementing This?
Our team can help you put these ideas into action. Get in touch for a free consultation.
Before writing anything, the agent counted what was in the source: 97 screen frames over nine pages. At 14:32 it asked one question in two parts.
- Scope. There were four options, from "tokens only" up to "tokens + every screen". The agent priced the largest at about 194 frames and "many hours of Figma calls". It recommended the tokens plus the main screen of each of the app's ten areas, and to "expand after you review".
- Poses. It recommended the outer display plus the inner display opened flat, and cited the guidelines' line about size classes covering every pose. The inner display held upright was offered as an extra.
The developer picked both recommendations two minutes later. Until the work was finished, that was the developer's only input.
Copying the tokens
A Figma script runs against one file at a time, so nothing moves between files on its own. The agent tested the obvious shortcuts first. The plugin's client storage threw "not a supported API", and neither fetch nor a compression API existed. Everything had to travel through the conversation: read from the source as JSON, then written into the target as code.
The first export came to 48 KB, more than the 20 KB a script may return. Split into three, it arrived:
- 44 primitive colours
- 36 semantic colours, each with a light and a dark mode
- 15 spacing values, 10 radii and 22 typography values
- 20 text styles and 4 shadows
Two write scripts recreated all of it with its aliases, scopes and code syntax, and the agent checked the counts against the source. The copy is faithful down to a quirk: the source's text-style descriptions contain HTML entities such as < as literal text, and so do the copies.
Images took a different route. The tab-bar icons are PNG files and one notification icon is a vector. The agent downloaded them with Figma's asset tool and uploaded them to the new file, so no image data had to pass through the chat.
Then it added one collection the source doesn't have. Duo Layout has an Outer mode and an Inner mode, and eight variables: display width and height, rail width, content width, both pane widths, the fold position and the home-indicator inset. Every screen frame binds its width and height to these and is set to one of the two modes, so each frame takes its size from its display.
The skill from Part 14 earned its keep
Part 14 turned seven memory notes about Figma into a user-level skill. This was the first large job to load it, and two parts of it shaped the run.
- Reading frames by script. The skill says that a script which walks a frame and prints an outline costs about a tenth of the tokens of Figma's standard design-context tool. The agent read all ten source screens and their shared components this way in about six minutes, and took one screenshot of each screen.
- The silent traps. Before its first write, the agent saved a prelude of helper functions to its scratch folder and pasted it at the top of every script. Three of the helpers exist because of traps the skill lists. Colour fills are built from the variable's resolved value, because a variable-bound fill that keeps a black placeholder renders black. Containers are set back to hugging their content after
resize(), which pins them to a fixed size. Text that should wrap is switched to auto-height before it is stretched, or it collapses to one word per line.
A ledger file in the same folder recorded every node ID as it was created, so nothing depended on the conversation remembering it.
Building it
Most of the build went into nine large scripts of 13 to 19 KB each, with screenshots after every one:
- Four component batches, 14:50 to 14:56. They hold 34 icon components, buttons, chips, form controls, list rows and cards, plus the Duo pieces: a status column, rail buttons, a tab rail and a
Railcomponent.Railhas an Outer and an Inner variant and a switch for each toolbar button, so each screen turns on only what it needs. - Five screen batches, 14:58 to 15:06. Each covers two screens. Every screen gets an outer frame, an inner frame and a notes panel that says what changed and which guideline drove it.
On the inner display the agent added one level of hierarchy, the way the guidelines show Mail with its list and an open message side by side:
- Two list screens, one of them the account page, became a list with a detail pane beside it.
- The notifications filter, a bottom sheet on today's phones, became a panel that stays open.
- Sign-up stays a bottom sheet on the outer display and becomes a centred sheet on the inner one, which is where Apple puts sheets on that display.
What the screenshots caught
One script failed outright. A pane's layoutGrow was set to a fraction, and Figma accepts only whole numbers. The run rolled back. Before retrying, the agent ran a read-only check to confirm that nothing partial had landed.
Every other defect passed the structural checks and showed up only in a screenshot:
- The fold line was invisible. The dashed line had been rotated outside its own frame. It became a solid bar one point wide.
- The FOLD label covered content. The agent moved it, then turned it into a switch that is off on screens and on in the documentation.
- A menu row read "Personal Deta". The title didn't wrap in the narrower right pane. Every variant of the row now wraps.
- The sign-up screen showed a signed-in home page behind the sheet. Someone signing up can't already be signed in. The agent read the source's guest version of the header, which has no notification bell, and used that.
- The documentation page and the cover were clipped. One diagram was cut off at the right edge, and the cover title stopped at "User Ap…".
The final audit found:
- 20 screen frames at the right sizes and modes, with 513 component instances and 604 text layers between them.
- No fills holding a black placeholder, and no fonts other than the source's text typeface and icon font.
- Only a few raw colours: white, black, a hidden placeholder grey, and colours that are hard-coded in the source as well.
- After the uploaded icon frames were deleted, all 44 layers that use their images still rendered.
The numbers
| Measure | Result |
|---|---|
| Developer input | The request and one answer |
| Time | 40 minutes of work; 42 from request to report, including the two-minute wait for the answer |
| Figma scripts | 56, plus one call made with the wrong tool name |
| Screenshots | 31 |
| Failed runs | 2, the oversized export and the fractional layoutGrow; both rolled back cleanly |
| Output | 127 copied variables and 8 new layout variables, 20 text styles, 4 shadows, a component library, 10 screens on 2 displays with notes, a foundations page and a cover |
The agent closed with a report that began with what it hadn't done: "Nothing has been checked in Apple's Xcode 27.1 simulator (Device Hub) or on a real device." It saved two memory notes, one with the new file's layout and one separating Apple's published facts from the derived ones.
Our calls, not Apple's
The foundations page keeps Apple's rules apart from the agent's own decisions, and labels each decision as one:
- An 80-point rail in the brand colour. The shipped status bar and tab bar already use that colour. On a page themed in another brand's colour, the rail takes that colour, as the shipped tab bar does.
- A 386-point content column on the outer display, four points narrower than today's 390, so most screens carry over almost unchanged.
- Inner panes split exactly at the fold. The leading pane gets 445 points and the trailing pane 365, after the rail. Header bands span both panes, which the guidelines allow: "letting a background image or header span the full width while scrollable content stays inset".
- New copy. An empty detail pane tells the user to pick an item from the list. That text isn't in the shipped app and needs product sign-off.
Re-reading the guidelines for this post raised a doubt about the third decision. In Apple's screenshot of Notes fully open, the leading pane is narrower than the trailing one. The panes become equal only when the phone is partly folded. Splitting at the fold copies the folded geometry. Flat, Apple's own app gives the detail side more room, and ours gives it less. That goes on the review list.
What the design can't do on its own
The consumer app's tab bar and headers are custom React Native views, and every navigator has the native header turned off. iOS moves its own bars to the side on this phone, but it won't move ours. The rail in the file has to be built in React Native and switched on the size class or the window width.
Keeping the custom sheet and rail clear of the fold when the phone is partly folded means calling Apple's new ReservedRegion API from native code. The partly folded pose and the inner display held upright aren't drawn yet.
What we don't know yet
- The point sizes. Nothing has been checked in the simulator or on a device. If the scale factor isn't 3, every frame changes size. Only the eight Duo Layout variables would need editing, but every layout decision would need another look.
- Whether the decisions hold. So far the developer's only response to the file has been to ask for this post.
- The other 87 frames, with their loading, empty, error and sheet states.
- The filter panel. Should it keep its Filter and Cancel buttons, or filter instantly now that it is always visible?
What to copy
- Research a device that is newer than the model, and keep the source. Save the primary page locally, so rules get quoted rather than remembered.
- Mark derived numbers as derived, in the design file itself, next to where they are used.
- Count before asking, and ask once. "97 frames, about 194 at both sizes" made the scope choice easy.
- Give device geometry its own variable collection, with one mode per display, and bind frame sizes to it.
- Write known traps into a helper you paste into every script, and keep node IDs in a ledger file, not in the conversation.
- Screenshot after every batch. The worst defects here were structurally valid.
- Keep your decisions apart from the platform's rules, so a reviewer knows which ones are open to debate.
- Say what the design can't do in code. Custom views don't get the platform's adaptations for free.