Scaling one product across web and iOS without rebuilding
“Wizard had no published design system, I was the only product designer, and iOS work already had a fixed start date. I chose to build the web foundations in my first month so the second platform would not inherit the same inconsistencies.”
Context
Roles & Responsibilities
Role:
Staff Product Designer
Responsibilities
Token architecture and binding rules
Component library, states, and documentation
AI assisted handoff pipeline
iOS port and divergence governance
Audit
This is the original interface audit.
Local components, screen mocks, and experiments lived together without a clear publishing boundary.
Colors were unlinked, spacing differed between cards, and interaction states were not defined consistently.
With no dedicated QA team, I ran bug bashes and kept returning cosmetic corrections to front end engineering.
I did not measure that cost in hours. The evidence here is the repeated work and the lack of an authoritative specification.
A fixed iOS date made those problems urgent because the second platform could inherit them.
A fixed iOS date changed the ROI calculation
Building a full system can be the wrong investment for an early product.
It takes time to maintain, and reuse may never arrive.
At Wizard, reuse already had a date: iOS design started on June 22. I chose to establish the web foundations while more than thirteen workstreams continued in parallel.
The decision was to prevent design debt from being copied into a second platform. The web foundations took about thirty days. The architecture later ported in one day, while the iOS library and product flows developed over six weeks. Those are different scopes of work, not competing timeline claims.
Decisions
Operating model
The file split established an operating model.
Foundations and components became the published reference. Icons had their own maintenance boundary. Feature specifications described product behavior, and the sandbox held experiments.
This was a release safety decision: an exploratory change should not silently become a production standard. A mixed file can technically publish components; the problem was the lack of a reliable boundary between approved and experimental work.
I built a custom product language while preserving platform behavior, rather than treating custom design as a reason to replace native conventions.
Decision 1 - Architecture
I chose three tiers instead of a flat palette: primitive values, semantic roles, and component tokens. Read this diagram from left to right as change propagation.
A primitive change reaches the semantic roles and component tokens bound above it.
Resolution runs in the opposite direction. Components normally bind to L3, with approved exceptions named in the contract.
The source trace is an illustration of the binding model, not proof that separate web and iOS files synchronize automatically.
The cost was more architecture work at the start. The benefit was a structure I could port without rebuilding the naming and binding model.
Decision 2 - Governed AI handoff
Most design systems still depend on someone interpreting the design during handoff. I wanted the same rules to constrain AI output. A Figma plugin generated YAML with component identity, variants, token references, and an MCP playbook.
DESIGNSYSTEM.md defined the binding rules and approved exceptions. Claude Cowork held project context, Figma MCP read the source, and Claude Code used those artifacts during prototyping. These enlarged fields come from the existing recommendation card export.
Extraction and repetitive work could be automated, while architecture and exception decisions remained mine. Human and engineering review is the final gate in this workflow; generated specifications are not evidence of production code parity or automatic compliance.
Decision 3 - iOS Platform adaptation
I first ported the architecture with naming parity, then documented each intentional difference. Hover became pressed because touch has no pointer hover.
Typography moved from Inter to SF Pro after an evaluation recorded on the canvas. Dark mode lived at the semantic tier, so components could inherit its roles. Web layout tokens remained for naming parity but were marked not to bind on iOS. Independent libraries risk drift, while a shared release dependency can slow native changes. This approach kept shared meaning while allowing platform conventions to differ. The dated decisions make those differences inspectable, rather than hiding them as implementation drift.
Governance
The operating model needed to work beyond my own memory.
Primitives and patterns were published from separate sources in July. Component retirement had a written process with a named replacement, and a second designer onboarded from the documentation in Q3.
Engineering received foundations, feature specifications, and the change log as shared implementation references. That is evidence of transfer, but it is not a complete adoption measurement. Some governance still depended on me. The next step was to make approval and deprecation authority explicit for the team maintaining the system.
Documentation
The operating model needed to work beyond my own memory.
Primitives and patterns were published from separate sources in July. Component retirement had a written process with a named replacement, and a second designer onboarded from the documentation in Q3.
Engineering received foundations, feature specifications, and the change log as shared implementation references. That is evidence of transfer, but it is not a complete adoption measurement. Some governance still depended on me. The next step was to make approval and deprecation authority explicit for the team maintaining the system.
Outcomes
Speed, scale and transferable ownership
The web foundations took about thirty days. The token architecture port took one day. Over six weeks, the iOS library reached 102 components and supported 24 product flows, with delivery including TestFlight.
A second designer onboarded from the documentation, and coding agents used the same rules. The recurring cosmetic issues I had logged no longer appeared in subsequent bug bashes after the references reached engineering.
That is an observation from my records, not a causal defect reduction percentage. Web component sets and iOS components are different units, so I do not compare those counts as growth. Exact engineering hours saved and adoption rates were not measured.