Achieving Design–Code Parity
Created a verification first workflow that aligned the design system with production code and enabled safe, scalable token migration across the app

Toggle for a quick summary or the full breakdown
Case study
Design to code parity
Flynas is a flight booking app that grew for years without a real colour system. I used an AI workflow to find every colour actually in use, clean it up, and prove not just assume that the design file and the shipped app has parity.
Role
Product Designer
Platform
iOS (Swift- Swift UI)
Timeline
1 week, May 2026
Tools
Figma, Cursor
Phase - 1 What was the problem
Flynas's app didn't have a real design system. Colours had been added one at a time over a couple of years, by whoever needed one at the time, with no shared list to check against. There was no way to say for certain what colours the app was actually using, or whether the Figma file matched what people would see on their phones. This created two kinds of risk:
The design file couldn't be trusted on its own. A colour might look correct in Figma, but show up differently or not at all in the live app.
Engineering had no single source to build from, so the same colour kept getting recreated slightly differently, again and again, across hundreds of files.
Why this mattered right now
Flynas already had a colour system defined in Figma I was using it and extending it as I worked on new screens, not building it from scratch. On the design side, things looked fine.
The problem was on the other side of the fence. The tech team had no single source of truth to build from. There was no verified link between what Figma said a colour should be and what the app actually used — engineers were picking values however they always had, screen by screen, with nothing to check against. So even though the Figma file was solid, nobody could say with confidence that it matched what was shipping.
That's a dangerous kind of gap, because it's invisible until someone actually checks. A designer can keep scaling a clean, well-organised Figma file for months, and it means nothing if the app quietly drifted somewhere else the whole time. Closing that gap — proving code and Figma actually agreed, not just assuming they did — became the real goal.
My goal
I set out to answer three questions, in order
What colours is the app actually using right now?
Which of those are duplicates?
Does it actually match what's defined in Figma and if not, where exactly does it disagree?
Answering all three properly by hand wasn't realistic the app has over a thousand code files. So I used Cursor, an AI coding assistant, as a research partner: it did the heavy searching and listing, and I made every judgment call about what the findings actually meant and whether to trust them.
How I approached it
On paper, this sounds simple: list the colours, clean them up, compare them to Figma. In practice, each step had a real decision buried in it a place where the easy answer would have been the wrong one. Here's where it actually got hard.
List Everything
Find every color used in the app
Group the mess
Judge each colour by its real value,
Double check it
Verify the numbers before trusting them
Compare
Check it against the design file
Step 1 - Find every file that touches colour
The app has over a thousand code files. No one could check them by hand, and even trying would only catch colours sitting neatly in style files, not the ones typed randomly into screens with no pattern.
So the first job was mapping where colours could be hiding.
PROMPT
Model used - Opus Extra 4.7
I'm auditing this iOS codebase to find every place colors and styles are defined, so I can compare them against my Figma design system and find parity gaps. Don't change any code yet — this is a read-only audit.First, find every file that defines colors or visual styles. Look for:
- Files named Colors.swift, Theme.swift, AppColors.swift, or similar
- Any .xcassets color set folders (Assets.xcassets)
- Any UIColor(...) or Color(...) calls scattered directly in view files
- Any files with "light" and "dark" or "Any Appearance" color variants
List every file you find that matches, with full path. Don't extract values yet just give me the inventory of files first.
This was just a map of where to look not the colours themselves yet. But even at this stage, the size of it was a shock. Over a thousand places, scattered everywhere, with no single list connecting any of them.
Step 2 - Open the central files and see what's actually inside them
PROMPT
Model used - Opus Extra 4.7
Open these three files and show me their full contents, unmodified:
- /Users/user/Downloads/Code Flynas /flynas-iOS-dotRez/Reusable Components/AppColors.swift
- /Users/user/Downloads/Code Flynas /flynas-iOS-dotRez/Reusable Components/AppFonts.swift
- /Users/user/Downloads/Code Flynas /flynas-iOS-dotRez/Reusable Components/AppButtons.swift
Then summarize: how many color variables are defined in AppColors.swift, what naming convention they use (e.g. primaryText, brandBlue), and whether each one has a light/dark mode variant defined inline or relies on a separate colorset.
This step didn't reveal a single actual colour yet. What it revealed was the shape of the problem. AppColors.swift held 204 separate colour cases in one enum, with no consistent naming pattern across them. None of the 204 stored a real colour value directly. Every one of them was just a pointer, referencing a separate entry in the asset catalog.
Step 3 - Pull out the actual colours
With the structure understood, the next step was going through all 204 pointers and finding out what each one actually resolves to, in both light and dark mode, and using that same pass to flag anything that looked broken or suspicious.
PROMPT
Model used - Opus Extra 4.7
For the 204 colorTypes in AppColors.swift, group them by what they're visually doing, not their current name. I want a table:
| Current Name | Resolved Light Value | Resolved Dark Value | Proposed Semantic Group |
Use semantic groups like: Brand, Text-Primary, Text-Secondary, Background, Border, Status-Success, Status-Error, Disabled, etc.
Also separately list:
1. The 4 broken tokens (errorColor, disabledColor, aliceBlue, the typo one) and what color they SHOULD probably resolve to based on their name and where they're used in the codebase
2. Any tokens whose resolved light/dark values are near-identical to another token (likely duplicates with different names)
The output
A perfect example to showcase misalignment

This is where the real data appeared, 204 actual colours with real hex values in both modes, laid out side by side, not just names. The same pass also surfaced two useful leads: 4 tokens that weren't actually connected to any real colour at all, and a first list of tokens whose values were close enough to look like possible duplicates.
Neither of those lists was something to accept as-is. A tool flagging two values as "near identical" is a starting point, not proof, the same way a usage count needed checking before it could be trusted. Both lists still needed to be verified against how each token was actually used before treating any of them as confirmed.
Step 4 — Don't trust the first answer
The storage mechanism was fine. Colours lived in the asset catalog, correctly, exactly where they should. But having the right mechanism didn't mean the information Cursor reported about that mechanism was automatically correct. That distinction became the whole point of this step.
One colour was reported as being used 160 times, supposedly for a specific kind of badge across the app's bundle pricing screens. When I asked to see ten real examples, none of them were badges. The number itself was wrong too, the real count was 8, not 160.
ISSUE -
A reported usage count didn't match reality
PROMPT
Model used - Auto
Show me 10 random call sites in the codebase that use .standardWhiteBlack [...] Same for .standard — show me 10 random call sites for that too.
That's not a small error to find midway through a project you've already built several conclusions on top of. If that one number was wrong by 20 times, every other number I hadn't personally checked was suddenly suspect too. The honest reaction wasn't relief at catching it, it was a genuine "wait, what else is wrong" moment.
ISSUE -
Root cause, and whether to trust the rest
PROMPT
Model used - Auto
You previously said .standard had 160 usages and mapped it to product/bundle-tag. I checked the actual codebase and found only 8 Swift references plus 1 storyboard usage- none of them are bundle-related.
They're selection borders, password-strength indicators, and dark-mode icon backgrounds.
Re-verify: where did the 160 number come from? Then correct the token-collapse-map.md row for .standard — either merge it into brand/accent if the hex is close enough, or give it an accurate semantic name based on its real usage (something like brand/accent-alt or status/success depending on majority use). Update the file in place.
The counting had mixed up two completely unrelated things sharing a similar name, like confusing two people with the same first name. The real usage had nothing to do with bundle pricing at all.
Rechecking all 204 colours properly meant redoing work I thought was already finished. It found nine more errors, including one colour no longer used in the app at all.
This became the most valuable, and most uncomfortable, habit in the whole project: a confident, specific sounding answer is not the same as a correct one, and the only way to know the difference is to go looking for reasons to doubt it, not reasons to accept it.
Step 5 — Check it against the real design file
With a verified list in hand, the real question was simple: does any of this actually match Figma? I pulled the live variables straight from the design file and compared them against what the app was actually using, colour by colour, mode by mode.
The result-
14
Colours matched exactly
44
looked similar, but didn't match
23
existed on only one figma
The result: only 14 tokens matched exactly. 44 existed in the code too, but with slightly different values, close but not correct. 23 tokens defined in Figma had no matching entry in the codebase at all. That meant 78% of the design system had drifted from what people were actually seeing on their phones, either the value was wrong, or the token wasn't represented in code in the first place.
Phase 2 — Proving it works in real code
Finding a problem and fixing it are two different jobs. A finished audit is just a document until you test it on something real. So instead of changing all 431 places at once, I picked one real screen to fix and test first: the trip card on the My Trips tab.
Why this screen, and what before and after actually looked like
I picked this screen on purpose, because it had already been fully analysed earlier in the project. I knew exactly what each text label on it was for, and I already knew which correct Figma colour each one should be using. In other words, the thinking was already done. What had not been done yet was actually changing the code.
Before
Seven text labels (date, times, stations, layover text, PNR) were pulling from standardWhiteBlack, a colour invented directly in code with no equivalent in Figma.
Four hero elements, the city title, flight chip text, time-left label, and guest chip text, were using a legacy token, themeWhite, that happened to resolve to the right colour by coincidence, but wasn't connected to Figma at all..
The two airport codes were using textColorsTextPrimary1, the dark grey/black primary text colour, when Figma specifies they should be teal, a real, visibly wrong colour that was live in the app.
The "Non-stop" label and the flight duration text were both borrowing iconFrameColorsFrameBrand, a token built for icon frames, to colour text, the right shade by luck, the wrong token by role.
After
The seven original labels now use textColorsTextPrimary1, matching Figma exactly.
The four hero elements now use textColorsTextWhite, a new token created directly from Figma's Text colors/text-white.
The airport codes now use textColorsTextTeal, a new token created from Figma's Text colors/text-teal, correcting a colour that was genuinely wrong before, not just unconnected.
The "Non-stop" label and duration text now use that same textColorsTextTeal token, properly sourced from a text role instead of an icon role.
One more element, the secondary button's text and border, was checked against Figma and confirmed already correct as it stood. Figma has no single "outlined button" token, it uses two separate tokens for text and border, and the card was already using exactly those, with values matching Figma precisely in both light and dark mode. Applying the same background token used on the primary button here would have actually broken dark mode, so it was deliberately left untouched.
Passing it on to the developers
Once this one screen was proven to work, this became something else: proof that the method works, not a finished job. I shared the fix and the full list of matched colours with the iOS development team, walked them through exactly how and why it worked, and handed over the responsibility of applying the same fix to the rest of the app. From there, it became their work to carry forward, which is exactly how it should go once the idea has been proven to actually work.
Oops, looks like you're on tablet. Sorry for the inconvenience. This portfolio is designed for desktop for now.
Oops, looks like you're on mobile. Sorry for the inconvenience. This portfolio is designed for desktop for now.













