I didn't wake up one morning and decide, Right, today I'm a developer now. That would be a lie. A neat one, maybe, but still a lie.

It started with irritation: buttons that did not behave like the design, hover states that felt off, and motion that evaporated somewhere between Figma and production. I knew what was wrong, but I was not the person fixing it.

So I moved closer to the fix.

I wrote this after my first six months contributing production code as a Senior Product Designer. Since then, that overlap has become a formal part of my work. I now lead UX and product engineering at Endla.

The point of the story has not changed. Getting closer to implementation made me more accountable for whether design intent survived.

Working with a clear boundary

My scope was the front end: component architecture, interaction states, TypeScript at a practical level, and the details that determine whether design intent survives.

I was not working alone or pretending review was optional. Experienced engineers reviewed my pull requests, challenged API decisions, and caught edge cases outside my depth.

AI tooling accelerated navigation and iteration, but it did not replace that accountability. I still had to understand the change, explain it in review, test it, and own the result.

The work itself was concrete

In that first six months I shipped and refined core components including tabs, buttons, badges, and cards. I replaced hardcoded values with semantic tokens, added keyboard and focus behaviour, and documented states and edge cases in Storybook.

The work involved sizes, states, variants, motion, theming, and component APIs that still made sense when the second use case arrived.

Some days it felt great. Other days it was painfully slow. Both were true.

Tokens over guesswork

One pattern appeared in almost every pull request: removing hardcoded values and replacing them with tokens.

Colours lived as hex codes for no clear reason. Spacing drifted depending on who last edited a file. Motion and opacity values looked like decisions but had no shared rationale. Those values steadily moved back into a system.

This is where being a designer in the codebase helped. I was not discovering intent. I was translating it and testing whether the abstraction held up.

I leaned on engineers for scalability, performance implications, and API design beyond the obvious. I could get something working, then work with the team to make it right.

That collaboration was the job.

Accessibility became interaction design

Keyboard order, ARIA relationships, focus-visible states, and disabled behaviour all had to work in the browser, not just appear in a specification.

I researched and implemented gaps the product had carried for years, then used engineering review and testing to strengthen the result. Once you have shipped and fixed a broken focus order, the lesson stops being abstract.

Accessibility stopped feeling like a checklist. It became interaction design with consequences.

Shipping the unglamorous improvements

Working in the codebase also meant I could push small interface improvements without a long design-to-development loop.

I fixed layout behaviour, refined collapsible sidebars with proper transitions and labels, and corrected button hierarchy that had drifted through historical decisions. None of it was groundbreaking. All of it made the product feel more considered.

That kind of polish rarely survives a handoff. It has a better chance when someone owns it through release.

Documentation is still design

I documented components through Storybook examples, usage notes, states, and edge cases because ambiguity is expensive.

Clear patterns reduce debate and prevent the same mistakes from returning when someone new encounters the component six months later. A design system can have excellent components and still fail if nobody knows how to use them.

What changed in my design practice

Working in code changed how I design because I began to feel the downstream cost of decisions directly.

I became more conservative with novelty, more deliberate about patterns, and less abstract in conversations about feasibility. When an idea compiles, breaks, or creates an awkward API, the feedback loop is clear.

Designers do not need to become engineers. But when the team and the work allow it, moving closer to implementation changes the quality of the questions you ask. Feasibility becomes concrete. Accessibility becomes behaviour. Polish becomes something you can own instead of annotate.

I stopped worrying about which title made the overlap legitimate. The useful part was simpler: I could follow an interaction farther, learn from where it broke, and stay accountable until it shipped.