<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Phong Designs AI System</title>
    <description>The latest articles on DEV Community by Phong Designs AI System (@phongdesigns).</description>
    <link>https://dev.to/phongdesigns</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4065211%2Facef7d58-130c-4304-bfae-e54efd6caa2c.png</url>
      <title>DEV Community: Phong Designs AI System</title>
      <link>https://dev.to/phongdesigns</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/phongdesigns"/>
    <language>en</language>
    <item>
      <title>Why Claude-generated screens are missing their states</title>
      <dc:creator>Phong Designs AI System</dc:creator>
      <pubDate>Fri, 07 Aug 2026 06:02:48 +0000</pubDate>
      <link>https://dev.to/phongdesigns/why-claude-generated-screens-are-missing-their-states-45gd</link>
      <guid>https://dev.to/phongdesigns/why-claude-generated-screens-are-missing-their-states-45gd</guid>
      <description>&lt;p&gt;Ask for a screen and you get the screen on its best day. Full of content, nothing loading, nothing failed, permission already granted, network fine. The product as it appears in a case study rather than as it appears on a Tuesday.&lt;/p&gt;

&lt;p&gt;This gets described as a limitation of the model. I think it's more specific than that, and the specificity is useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  It learned from portfolios
&lt;/h2&gt;

&lt;p&gt;Nearly every image of an interface that exists publicly is a marketing image. Screens on landing pages, screens in case studies, screens in design galleries — all of them curated, all of them full, all of them at their best.&lt;/p&gt;

&lt;p&gt;Almost nobody publishes the empty state. Nobody puts the error screen in their portfolio. So a model asked for "a booking screen" produces the version it has seen ten thousand times, which is the version where everything went right.&lt;/p&gt;

&lt;p&gt;It isn't failing. It's returning exactly what it was shown. The gap isn't in its capability, it's in what the world bothered to photograph.&lt;/p&gt;

&lt;h2&gt;
  
  
  Screen count is the number that misleads everyone
&lt;/h2&gt;

&lt;p&gt;On a booking product: 68 functions, 44 in the MVP, seven flows, 28 main screens.&lt;/p&gt;

&lt;p&gt;Twenty-eight sounds like a small project. The real artboard count came out several times higher, because a screen isn't finished until it has states — loading, empty, error, permission, offline, whatever this particular product can actually do to a user.&lt;/p&gt;

&lt;p&gt;That multiplier is where estimates die. A team quotes 28 screens, generates 28 screens, feels ahead of schedule, and then spends the back half of the project discovering that each one has three or four siblings nobody counted. Same work, discovered late, at the worst possible moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  States are product decisions wearing visual clothes
&lt;/h2&gt;

&lt;p&gt;This is the part I'd argue hardest for.&lt;/p&gt;

&lt;p&gt;An empty state isn't a screen with the content removed. It's an answer to: this person has nothing here yet — is that because they're new, because they filtered everything out, or because something failed? Three different situations, three different messages, three different actions, and only one of them is "add your first item".&lt;/p&gt;

&lt;p&gt;An error state isn't a red box. It's a decision about whether the user can recover, whether they lose what they typed, whether it's their fault, and whether telling them the technical reason helps or frightens them.&lt;/p&gt;

&lt;p&gt;A model can generate any of these convincingly. It cannot decide which situation you're actually in, because that information was never in the brief — and it will not stop to ask. It will pick the most common one and render it beautifully.&lt;/p&gt;

&lt;h2&gt;
  
  
  So the states get named before generation, not after
&lt;/h2&gt;

&lt;p&gt;Every screen carries its required states as part of the screen list, decided when you still remember why the screen exists.&lt;/p&gt;

&lt;p&gt;Doing it afterwards has a specific failure mode I've watched several times: the states get added as visual variants of a finished screen, so they inherit its layout, and you end up with an empty state that has a filter bar controlling nothing and a table header above no rows. It's technically an empty state. It's nonsense as a piece of product.&lt;/p&gt;

&lt;p&gt;Deciding first also surfaces the questions that should have been asked in the brief. Half the states nobody wrote down are the ones where the answer is genuinely unknown, and that's exactly the conversation worth having early.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same applies to components
&lt;/h2&gt;

&lt;p&gt;A component that appeared once in one screen will be modelled in one state, because that's the evidence available.&lt;/p&gt;

&lt;p&gt;But an input has focus, filled, disabled, error, read-only. A button has pressed, disabled, loading. A checkbox has an indeterminate state that will absolutely appear the moment someone builds a bulk-select. If the library only carries what happened to show up on a screen, the missing states get improvised later by whoever hits them first — usually a developer, usually under time pressure, usually differently in three places.&lt;/p&gt;

&lt;p&gt;So the rule I use: you don't have to build every component archetype, but the ones you do build carry their full state matrix, whether or not a screen has demanded it yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is worth the effort
&lt;/h2&gt;

&lt;p&gt;Because states are where the product actually meets its user. Nobody's experience of a product is the marketing screenshot. It's the day the search returned nothing, the day the payment failed, the day they opened it on a train.&lt;/p&gt;

&lt;p&gt;The polished screens are the ones that get shown. The states are the ones that get used.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this doesn't solve
&lt;/h2&gt;

&lt;p&gt;You can over-specify this. I've built full state coverage for screens that turned out to be cut from the product, which is expensive work thrown away — and worse, it makes the state list feel like bureaucracy to everyone who watched it happen.&lt;/p&gt;

&lt;p&gt;There's also no clean rule for how far to go. Offline behaviour matters enormously for a field tool and barely at all for an internal dashboard, and the only way I know to tell the difference is to have thought properly about who's using it and where. Which puts you back at the beginning of the process, which is usually where the real answer is.&lt;/p&gt;

&lt;h2&gt;
  
  
  The whole thing, recorded on one real project
&lt;/h2&gt;

&lt;p&gt;I recorded the full path end to end — brief, structure and flows, generated screens, locked token system, Figma with real components and variables, clickable prototype, developer handoff — on a single project, breakages included:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://phongdesigns.com/course/claude" rel="noopener noreferrer"&gt;Claude AI UI/UX: Complete Workflow from Brief to Figma&lt;/a&gt;&lt;/strong&gt; — the same path on one real project, brief through to a Figma handoff.&lt;/p&gt;

&lt;p&gt;If you've got a state that's bitten you that most lists leave out, I'd like to know which one. Mine was permission.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>design</category>
      <category>ux</category>
      <category>figma</category>
    </item>
    <item>
      <title>Claude and Figma: bulk edits that don't break your file</title>
      <dc:creator>Phong Designs AI System</dc:creator>
      <pubDate>Thu, 06 Aug 2026 06:37:22 +0000</pubDate>
      <link>https://dev.to/phongdesigns/claude-and-figma-bulk-edits-that-dont-break-your-file-3fgd</link>
      <guid>https://dev.to/phongdesigns/claude-and-figma-bulk-edits-that-dont-break-your-file-3fgd</guid>
      <description>&lt;p&gt;I asked an agent to swap one colour value across a file. It did. It also rewrote the line that defined the value in the first place, so the definition now pointed at itself.&lt;/p&gt;

&lt;p&gt;Nothing errored. Nothing warned. The instruction ran perfectly, which is the whole problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every one of these has the same shape
&lt;/h2&gt;

&lt;p&gt;A single condition matched more than I meant, and everything that matched got changed.&lt;/p&gt;

&lt;p&gt;The second one I still think about: hiding a set of shadow rectangles also hid a keyboard, because the keyboard's parts satisfied exactly the same single condition. Again no error, again a clean report of success.&lt;/p&gt;

&lt;p&gt;Once you see the pattern it's everywhere. It isn't a model being careless. It's an instruction that was less precise than it felt while writing it, executed with total literalness by something that has no idea what any of these objects are for.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule: scope, and two conditions, never one
&lt;/h2&gt;

&lt;p&gt;Name the region it may touch. Not "the file" — this section, these frames, this layer group.&lt;/p&gt;

&lt;p&gt;Then give it two properties that must both be true. Not "everything with this colour" but "everything with this colour, inside this region, that is a fill rather than a definition". The second condition is doing the real work: it's what stops the match spreading into things that happen to share one attribute.&lt;/p&gt;

&lt;p&gt;It's a small amount of extra writing. It's the difference between a change and an incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  It cannot see the result — that's the fixed constraint
&lt;/h2&gt;

&lt;p&gt;An agent writes the change, the change renders somewhere it has no eyes on, and it reports success based on the instruction completing rather than the outcome being right.&lt;/p&gt;

&lt;p&gt;People treat that missing feedback loop as a tooling problem, something that will be solved in a future version. I don't think it is one. It's a sequencing problem, and sequencing is available today.&lt;/p&gt;

&lt;p&gt;The loop can't be closed by the agent. Fine. It can still be closed by a person — just not a hundred times.&lt;/p&gt;

&lt;h2&gt;
  
  
  One, then all
&lt;/h2&gt;

&lt;p&gt;Run the operation on a single representative case. Render it. Look at it with your own eyes, before and after. Only when that passes does the same operation run across everything else.&lt;/p&gt;

&lt;p&gt;Binding values, building components, swapping instances, generating images — same shape every time.&lt;/p&gt;

&lt;p&gt;This sounds obvious written down and almost nobody does it. The pilot feels like a waste when the batch is right there and the agent sounds confident. That confidence is the tell: it reports identically whether it produced one correct thing or a hundred wrong ones, because it isn't looking at the output, it's looking at whether the instruction ran.&lt;/p&gt;

&lt;h2&gt;
  
  
  The economics favour the pilot, which surprised me
&lt;/h2&gt;

&lt;p&gt;I assumed the careful path was the slower one. It isn't.&lt;/p&gt;

&lt;p&gt;One pilot plus one clean batch costs less in tokens, time and patience than one confident batch plus the unwind. And unwinding is much worse than redoing — you're now hunting for damage across a hundred items with no error message to guide you, and you can't be sure you found all of it.&lt;/p&gt;

&lt;p&gt;There's a second effect I didn't expect. Because a pilot is small, I actually look at it properly. When a hundred results land at once I skim, and skimming is precisely how the subtle wrong things get through — the ones that look plausible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bulk swapping will eat your real content
&lt;/h2&gt;

&lt;p&gt;Worth calling out separately because the damage is silent.&lt;/p&gt;

&lt;p&gt;When screen layers get swapped to component instances, the overrides are carrying real copy — actual names, actual prices, actual text somebody wrote. A careless bulk swap replaces all of it with the master's placeholder content, and you find out several screens later, if at all.&lt;/p&gt;

&lt;p&gt;This is the single most expensive small mistake in the whole process, because the damage is distributed and invisible unless you happen to open the right screen. Pilot it. Every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never accept a blanket fix
&lt;/h2&gt;

&lt;p&gt;Any tool that offers to correct everything at once is offering to guess, and the guess is usually "snap to the nearest value".&lt;/p&gt;

&lt;p&gt;Nearest is a visual measure, not a semantic one. A value that's visually closest is very often not the value that was meant, and once it's applied there's nothing left in the file recording that a choice was ever made. The system quietly acquires meanings nobody chose.&lt;/p&gt;

&lt;p&gt;Use those tools to find things. Decide the fixes yourself, or at least decide the categories and apply them deliberately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-run the whole check, not the part you touched
&lt;/h2&gt;

&lt;p&gt;After a change that crosses layers, checking only the thing you changed tells you very little. The failure mode of bulk operations is precisely that they affect things you weren't thinking about.&lt;/p&gt;

&lt;p&gt;So the check has to cover the same ground every time, including the parts you're confident about. Confidence is not evidence, and on the two occasions above I was completely confident.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this doesn't solve
&lt;/h2&gt;

&lt;p&gt;Pick the wrong representative case and the pilot passes while the batch still breaks. Choosing one that's hard enough to be a real test is a judgment call and I haven't turned it into a rule. I lean toward the messiest example rather than the cleanest, which is instinct, not method.&lt;/p&gt;

&lt;p&gt;And there's a cost to all of this: it's slower per operation, and on a small file that overhead can exceed what the damage would have been. I still run it, because the failures aren't proportional to file size — the keyboard incident happened in a file I'd have called simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  The whole thing, recorded on one real project
&lt;/h2&gt;

&lt;p&gt;I recorded the full path end to end — brief, structure and flows, generated screens, locked token system, Figma with real components and variables, clickable prototype, developer handoff — on a single project, breakages included:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://phongdesigns.com/course/claude" rel="noopener noreferrer"&gt;Claude AI UI/UX: Complete Workflow from Brief to Figma&lt;/a&gt;&lt;/strong&gt; — the same path on one real project, brief through to a Figma handoff.&lt;/p&gt;

&lt;p&gt;If a bulk operation has quietly eaten something of yours, I'd like to know what matched. Those stories are the most useful thing anyone has given me.&lt;/p&gt;

</description>
      <category>design</category>
      <category>ai</category>
      <category>figma</category>
      <category>ux</category>
    </item>
    <item>
      <title>Claude to Figma: keeping AI-generated UI bound to your design system</title>
      <dc:creator>Phong Designs AI System</dc:creator>
      <pubDate>Thu, 06 Aug 2026 06:16:54 +0000</pubDate>
      <link>https://dev.to/phongdesigns/claude-to-figma-keeping-ai-generated-ui-bound-to-your-design-system-4p8b</link>
      <guid>https://dev.to/phongdesigns/claude-to-figma-keeping-ai-generated-ui-bound-to-your-design-system-4p8b</guid>
      <description>&lt;p&gt;On one build I found 127 places bound to a raw colour instead of a named role. Every single one had passed visual review. They all surfaced the moment someone asked for dark mode.&lt;/p&gt;

&lt;p&gt;That number is the whole argument. Not because 127 is large, but because none of them looked wrong. A value that was typed in and a value that came from the system are visually identical. The difference only exists in what happens next.&lt;/p&gt;

&lt;h2&gt;
  
  
  The failure isn't that the agent breaks the rules
&lt;/h2&gt;

&lt;p&gt;It's that it extends them.&lt;/p&gt;

&lt;p&gt;Give an agent a design system and ask it to build. When it reaches something the system covers, it uses the system — genuinely, reliably. When it reaches something the system doesn't cover, it does not stop and ask. It invents. And what it invents is a name that sounds exactly like one of yours, sitting right next to the real ones, reading as though someone chose it on purpose.&lt;/p&gt;

&lt;p&gt;That's why this is so hard to catch by eye. A fabricated token isn't a glaring error. It's a plausible one. Six months later nobody can tell you whether it was a deliberate exception or a hallucination, and by then five components depend on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Readable is not the same as closed
&lt;/h2&gt;

&lt;p&gt;Making a library available to an agent gets you components it will reuse. It does not get you a closed set.&lt;/p&gt;

&lt;p&gt;A closed set means: these values exist, everything else does not, and anything outside them fails loudly rather than passing quietly. The distinction sounds pedantic and it decides everything. A readable system produces output that mostly matches. A closed system produces output you can audit.&lt;/p&gt;

&lt;p&gt;Which is the real test I'd apply to any AI design setup: not how much of your system it covers, but what happens to the things it doesn't cover. If those slip through silently, coverage is irrelevant — you've just made the drift harder to spot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layers, and not reaching past them
&lt;/h2&gt;

&lt;p&gt;Tokens have layers for a reason. Base values underneath — the raw material. Named roles on top — what a value is for. And the product interface binds to the role, never reaching past it to grab the raw value directly.&lt;/p&gt;

&lt;p&gt;It's a boring rule. It's also the one that decides whether a theme change is a switch or a rebuild.&lt;/p&gt;

&lt;p&gt;The reason it gets broken constantly is that reaching past a layer always works in the moment. The screen looks right. The rule only earns its keep later, when a value needs to mean something different in a different context and there's nothing in the file that knows the difference between "this blue" and "the colour a primary action uses".&lt;/p&gt;

&lt;p&gt;The same discipline applies to how many names exist. Every role you add is a decision someone else has to understand. A system that grows a new name every time a screen needs something slightly different has stopped being a system and become a very structured way of typing values in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull tokens from the interface, don't invent them first
&lt;/h2&gt;

&lt;p&gt;Writing a full token set before any interface exists produces two predictable problems: a pile of values nobody ever uses, and gaps at exactly the places where the real decisions turned out to be.&lt;/p&gt;

&lt;p&gt;I get much better results extracting the system from interface that already exists and has been reviewed — every value in it earned its place by being needed. What that produces is smaller, and everything in it is load-bearing.&lt;/p&gt;

&lt;p&gt;The order matters more than the format. A set derived from real screens knows what it's for. A set written in advance is a guess with good syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dark mode as an audit, not a feature
&lt;/h2&gt;

&lt;p&gt;This is the cheapest check in the entire process and almost nobody uses it as one.&lt;/p&gt;

&lt;p&gt;Flipping to dark stops asking the file what a value looks like and starts asking what it means. A value bound to a role knows how to behave in the other mode. A value typed in only ever knew how to look right in one context, and it fails immediately and visibly.&lt;/p&gt;

&lt;p&gt;Ten seconds, and it finds what a careful visual review across dozens of screens will not. That's how the 127 surfaced: not through diligence, but through a mode switch.&lt;/p&gt;

&lt;p&gt;If you only take one thing from this: after any large AI-assisted change, flip the theme before you look at anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-checks only work against something that can fail
&lt;/h2&gt;

&lt;p&gt;Asking a model to review its own work against a principle written in prose gets you agreement. It will confirm that yes, it used the design system, and it will believe that.&lt;/p&gt;

&lt;p&gt;Asking it to check output against a file of permitted values gets you a list of differences. One of those is a review. The other is a mood.&lt;/p&gt;

&lt;p&gt;So the check has to be mechanical: here is the set of legal values, here is what's in the output, show me what appears in one and not the other. Anything that can't produce a difference isn't a check.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this doesn't solve
&lt;/h2&gt;

&lt;p&gt;A closed set stops invention. It doesn't tell you whether the set is any good — constrain an agent to a badly designed system and you'll get consistent, coherent, thoroughly wrong output, delivered fast.&lt;/p&gt;

&lt;p&gt;And there's a cost people don't mention: closing the set means someone has to maintain it. Every genuinely new requirement now needs a decision rather than an improvisation. That's the point, and it's also work, and on a small project it can be more work than the drift would have cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  The whole thing, recorded on one real project
&lt;/h2&gt;

&lt;p&gt;I recorded the full path end to end — brief, structure and flows, generated screens, locked token system, Figma with real components and variables, clickable prototype, developer handoff — on a single project, breakages included:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://phongdesigns.com/course/claude" rel="noopener noreferrer"&gt;Claude AI UI/UX: Complete Workflow from Brief to Figma&lt;/a&gt;&lt;/strong&gt; — the same path on one real project, brief through to a Figma handoff.&lt;/p&gt;

&lt;p&gt;If you've run the dark-mode check on an AI-assisted build, I'm curious what your number was. Mine was 127 and I did not see it coming.&lt;/p&gt;

</description>
      <category>design</category>
      <category>ai</category>
      <category>figma</category>
      <category>ux</category>
    </item>
    <item>
      <title>Figma MCP: turning Claude-generated UI into a component library</title>
      <dc:creator>Phong Designs AI System</dc:creator>
      <pubDate>Thu, 06 Aug 2026 06:15:32 +0000</pubDate>
      <link>https://dev.to/phongdesigns/figma-mcp-turning-claude-generated-ui-into-a-component-library-72j</link>
      <guid>https://dev.to/phongdesigns/figma-mcp-turning-claude-generated-ui-into-a-component-library-72j</guid>
      <description>&lt;p&gt;This is the stretch nobody films. The demo ends at the screenshot; the job ends about a week later, in a Figma file that someone else has to be able to open without you in the room.&lt;/p&gt;

&lt;p&gt;It's also where roughly 40% of the work lives, and where most AI-assisted design quietly falls over — not because the screens are bad, but because nothing in them is addressable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import destroys the names
&lt;/h2&gt;

&lt;p&gt;Bring generated markup into Figma and everything arrives as a frame inside a frame inside a frame, with names that mean nothing. The structure survives. The meaning doesn't.&lt;/p&gt;

&lt;p&gt;The instinct at this point is to start componentising from what's on the canvas — find a button in a screen, make it a component, move on. Don't. That tree is a rendering artefact. Build your library from it and you inherit every accident in it: wrapper divs promoted to components, layout containers baked into masters, the same element modelled three different ways because it appeared in three different screens.&lt;/p&gt;

&lt;p&gt;The source markup is the specification. It knows what each thing is. So the first move is reading it and producing a record of what should exist and what it should be called — then renaming against that record, then componentising. Rename first, componentise second. Reversing those two costs more than any other ordering mistake in this stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Library first, screens second
&lt;/h2&gt;

&lt;p&gt;Masters get built in a clean library section, not harvested from inside screens.&lt;/p&gt;

&lt;p&gt;The difference shows up in what ends up inside the component. Harvested masters carry their surroundings — a padding wrapper that belonged to the screen, a demo label, a background that existed to make it visible on a dark canvas. Those things then travel into every instance, and six months later somebody is asking why every card has eight pixels of phantom padding.&lt;/p&gt;

&lt;p&gt;Same-structure things get grouped into a variant set rather than left as separate components. A button that arrives as five unrelated components instead of one set is the single most common breakage I hit here, and it has to be fixed at this point, because everything downstream references it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bind at the master
&lt;/h2&gt;

&lt;p&gt;Colour, type, elevation, effects — bound at the master, then the loose layers that live outside components get handled separately.&lt;/p&gt;

&lt;p&gt;Two rules that sound obvious and are broken constantly. First, binding changes only the style property; it must not disturb size, position, layout behaviour or constraints. Second, no snapping to the nearest value. A checker that offers to fix everything is offering to guess, and a guess that lands on the visually closest value is exactly how a system quietly acquires meanings nobody chose. Use the checker to find things. Decide the fixes yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Swapping will eat your real content
&lt;/h2&gt;

&lt;p&gt;When screen layers get swapped to instances, the overrides carry real copy — actual names, actual prices, actual text someone wrote.&lt;/p&gt;

&lt;p&gt;A bulk swap run without care replaces all of it with the master's placeholder content, and you find out screens later. This is the single most expensive small mistake in the whole stage, because the damage is silent, distributed, and only visible if you happen to look at the right screen.&lt;/p&gt;

&lt;p&gt;So: one representative screen first, checked with your own eyes, before and after. Then the rest. Every time. The pilot feels like a waste when the batch is right there and the agent sounds confident — that confidence is the tell, because it reports identically whether it produced one correct thing or a hundred wrong ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where MCP earns its place
&lt;/h2&gt;

&lt;p&gt;Some component structures are more complicated than a scripted build can shape — nested variants, states that interact, structures that need judgment about what belongs inside and what doesn't.&lt;/p&gt;

&lt;p&gt;That's where driving Figma directly through an agent connection pays: building the component with its real states, then swapping it into the screens, with a person deciding the shape and the tool doing the repetition.&lt;/p&gt;

&lt;p&gt;What it doesn't do is see the result. It reports that the instruction ran, not that the screen looks right. So the loop stays the same: it builds, you look, then it repeats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then flip the mode
&lt;/h2&gt;

&lt;p&gt;Before calling any of this done, switch themes and compare against the version you already approved.&lt;/p&gt;

&lt;p&gt;If Figma is wrong and the source was right, the binding is wrong — fix the binding. If both are wrong, the problem is upstream in the system itself, so fix it there and bring the change forward. What you must not do is patch the Figma file alone, because you've now got two sources of truth that disagree, and the file will win every argument until someone rebuilds it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this buys, honestly
&lt;/h2&gt;

&lt;p&gt;Done properly this removes something like 70–80% of the manual finishing work. Not 100%. There will be errors, there will be a pass where you fix things by hand, and anyone promising a single click to a perfect file has not shipped one.&lt;/p&gt;

&lt;p&gt;But 70–80% of the least interesting work in the project is a real number, and it's the difference between a workflow that ends at a pretty screenshot and one that ends at a handoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this doesn't solve
&lt;/h2&gt;

&lt;p&gt;It doesn't decide what should be a component. That's a judgment call about what will repeat and what won't, made before there's evidence either way, and I still get it wrong on unfamiliar product types.&lt;/p&gt;

&lt;p&gt;And "ready for handoff" is a safer claim than "a developer can start immediately" until a developer has actually opened it. I've learned to say the first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The whole thing, recorded on one real project
&lt;/h2&gt;

&lt;p&gt;I recorded the full path end to end — brief, structure and flows, generated screens, locked token system, Figma with real components and variables, clickable prototype, developer handoff — on a single project, breakages included:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://phongdesigns.com/course/claude" rel="noopener noreferrer"&gt;Claude AI UI/UX: Complete Workflow from Brief to Figma&lt;/a&gt;&lt;/strong&gt; — the same path on one real project, brief through to a Figma handoff.&lt;/p&gt;

&lt;p&gt;If you've found a reliable way to keep real content through a bulk swap, I'd like to hear it. That one still costs me time.&lt;/p&gt;

</description>
      <category>design</category>
      <category>ai</category>
      <category>figma</category>
      <category>ux</category>
    </item>
  </channel>
</rss>
