Ticketbro
Design System
Ticketbro
Design System
I built the system behind Ticketbro's products so I could stop rebuilding the same patterns and start trusting the foundation.
I built the system behind Ticketbro's products so I could stop rebuilding the same patterns and start trusting the foundation.
Faster handoff
Faster handoff
Faster handoff
Shared components
Shared components
Shared components
Tokens set
Tokens set
Tokens set








Info
Role
Sole Product Designer
Platforms
Mobile, Web, Kiosk
Timeline
Core built Q1 2023, expanded through 2025
Team
1 Designer, Engineers
Tool
Figma
01
Background
Why this needed to exist
By the time I started building the system, Ticketbro's product was already taking shape. Features were shipping, new surfaces were coming, and I was the only designer working across all of them.
The problem wasn't the design quality. It was the process behind it. Every new feature meant rebuilding the same patterns. Every screen needed a light version first, then a manual dark mode pass: duplicating layers, swapping colors by hand, double-checking contrast. It worked, but it was slow, repetitive, and fragile. I'd occasionally overwrite something or introduce a small inconsistency without noticing. That created extra rounds in handoff where developers would flag mismatches or just quietly ignore parts of the design that didn't look intentional.
As the only designer, this wasn't sustainable. The product was growing faster than I could manually maintain consistency across it. So instead of continuing to patch things screen by screen, I stopped and built the foundation properly.
02
The structure
From values to components
I built the system in layers, starting from the most abstract and working up to the most concrete.
The first layer was base tokens: 101 raw values for color, spacing, radius, opacity, and typography. These are the numbers that never change regardless of theme or mode. Primary-500 is a specific blue. Spacing-16 is 16 pixels. No opinions, just values.
The second layer was semantic tokens: 149 mappings that give those values meaning in context. A button's surface color in its default state points to Primary-500 in light mode and Primary-400 in dark mode. The button doesn't know about hex codes. It knows about its own role and state. That separation is what made theming and dark mode manageable instead of manual.


Base values on the left, semantic structure in the middle, button tokens mapped across light and dark on the right.
02
The structure
The third layer was shared components. I built around 50 component groups following an atomic approach. But I was deliberate about what earned a place in the system. If a pattern showed up across multiple features or surfaces, it went into the shared library. If it was specific to one flow, it stayed inline in that project until it proved it belonged somewhere more permanent.
That rule kept the system lean. A bloated library full of one-off components would have been worse than no library at all, especially working alone.

Each shared component included Figma properties for customization. Key components also had short usage descriptions and documented use cases.
50+ shared component groups, each with variants, states, and theme support.

The same foundation reused across customer, provider, kiosk, and other surfaces.
Four themes, each in light and dark mode. Primary colors change, the system holds.
04
The tradeoffs
What I chose not to build
The system was built by one designer for a small team with shifting priorities. That meant making conscious decisions about where to invest time and where to leave things good enough.
I documented the components that needed it most. Ones with multiple variants, non-obvious rules, or behaviors that differed across platforms got short descriptions and usage guidelines. But I didn't reach that level of detail for every component. The simpler, more self-explanatory ones shipped without written guidance and relied on clear naming and consistent structure to communicate intent.
The same pragmatism applied to the library itself. Some components lived inline in specific feature files and never graduated to the shared library. I had a clear rule: if a pattern appeared across multiple features or surfaces, it earned a place in the system. If it didn't, it stayed local. That kept the library honest. But I wish I'd organized those inline components more consistently. When a project ended, the local pieces sometimes stayed scattered across files rather than being cleaned up or promoted.
We also made a mutual decision with engineering not to invest in a full documentation layer at that stage. At our team size and pace, the system could be understood from the file itself. Naming and structure were shaped with engineering input specifically so the system wouldn't need a manual to use. That was the right call for where we were, but it was a tradeoff, not an ideal.
If I were building this again, I'd set a minimum from the start: one line per component explaining when to use it and when not to. I'd also build a simple index of inline components per project so nothing gets lost between files. The system worked well because we were small and in constant communication. For a larger team or a handoff to another designer, those gaps would matter.
05
The impact
What changed because of it
The most obvious change was speed. Dark mode stopped being a second design pass. New features started from a reliable base instead of a blank file. I stopped rebuilding the same patterns and started spending that time on the problems that actually needed design thinking.
Handoff got noticeably lighter. Based on comparing the time spent on design-to-dev communication across a few features before and after the system, plus direct feedback from engineering, I estimated the system reduced handoff friction by about 25%. Developers liked the dark mode setup enough that they asked me to only share the dark version in handoff files, since they could trust the light version would be correct automatically.
But the less measurable change mattered more. The system built trust. I trusted the foundation, so I didn't have to double-check every screen against every other screen before handing it off. Engineering trusted it because the same components behaved the same way everywhere, and they stopped having to flag inconsistencies or guess at intent.
For a solo designer working across five product surfaces, that trust was the real output. The tokens and components were just how I got there.
Faster design-to-dev handoff
Shared component groups
Shared component groups
Tokens across base and semantic layers
06
Close
A design system built by one person will always reflect the constraints it was built under. This one isn't perfect. The documentation gap is real, and the inline components could be better organized. But it did what it needed to do: it let one designer move fast across an entire product ecosystem without the work falling apart.
The system is still the foundation of every Ticketbro product shipping today.
Ticketbro
Design System
Ticketbro
Design System
I built the system behind Ticketbro's products so I could stop rebuilding the same patterns and start trusting the foundation.
I built the system behind Ticketbro's products so I could stop rebuilding the same patterns and start trusting the foundation.
Faster handoff
Faster handoff
Faster handoff
Shared components
Shared components
Shared components
Tokens set
Tokens set
Tokens set








Info
Role
Sole Product Designer
Platforms
Mobile, Web, Kiosk
Timeline
Core built Q1 2023, expanded through 2025
Team
1 Designer, Engineers
Tool
Figma
01
Background
Why this needed to exist
By the time I started building the system, Ticketbro's product was already taking shape. Features were shipping, new surfaces were coming, and I was the only designer working across all of them.
The problem wasn't the design quality. It was the process behind it. Every new feature meant rebuilding the same patterns. Every screen needed a light version first, then a manual dark mode pass: duplicating layers, swapping colors by hand, double-checking contrast. It worked, but it was slow, repetitive, and fragile. I'd occasionally overwrite something or introduce a small inconsistency without noticing. That created extra rounds in handoff where developers would flag mismatches or just quietly ignore parts of the design that didn't look intentional.
As the only designer, this wasn't sustainable. The product was growing faster than I could manually maintain consistency across it. So instead of continuing to patch things screen by screen, I stopped and built the foundation properly.
02
The structure
From values to components
I built the system in layers, starting from the most abstract and working up to the most concrete.
The first layer was base tokens: 101 raw values for color, spacing, radius, opacity, and typography. These are the numbers that never change regardless of theme or mode. Primary-500 is a specific blue. Spacing-16 is 16 pixels. No opinions, just values.
The second layer was semantic tokens: 149 mappings that give those values meaning in context. A button's surface color in its default state points to Primary-500 in light mode and Primary-400 in dark mode. The button doesn't know about hex codes. It knows about its own role and state. That separation is what made theming and dark mode manageable instead of manual.


Base values on the left, semantic structure in the middle, button tokens mapped across light and dark on the right.
02
The structure
The third layer was shared components. I built around 50 component groups following an atomic approach. But I was deliberate about what earned a place in the system. If a pattern showed up across multiple features or surfaces, it went into the shared library. If it was specific to one flow, it stayed inline in that project until it proved it belonged somewhere more permanent.
That rule kept the system lean. A bloated library full of one-off components would have been worse than no library at all, especially working alone.

Each shared component included Figma properties for customization. Key components also had short usage descriptions and documented use cases.
50+ shared component groups, each with variants, states, and theme support.

The same foundation reused across customer, provider, kiosk, and other surfaces.
Four themes, each in light and dark mode. Primary colors change, the system holds.
04
The tradeoffs
What I chose not to build
The system was built by one designer for a small team with shifting priorities. That meant making conscious decisions about where to invest time and where to leave things good enough.
I documented the components that needed it most. Ones with multiple variants, non-obvious rules, or behaviors that differed across platforms got short descriptions and usage guidelines. But I didn't reach that level of detail for every component. The simpler, more self-explanatory ones shipped without written guidance and relied on clear naming and consistent structure to communicate intent.
The same pragmatism applied to the library itself. Some components lived inline in specific feature files and never graduated to the shared library. I had a clear rule: if a pattern appeared across multiple features or surfaces, it earned a place in the system. If it didn't, it stayed local. That kept the library honest. But I wish I'd organized those inline components more consistently. When a project ended, the local pieces sometimes stayed scattered across files rather than being cleaned up or promoted.
We also made a mutual decision with engineering not to invest in a full documentation layer at that stage. At our team size and pace, the system could be understood from the file itself. Naming and structure were shaped with engineering input specifically so the system wouldn't need a manual to use. That was the right call for where we were, but it was a tradeoff, not an ideal.
If I were building this again, I'd set a minimum from the start: one line per component explaining when to use it and when not to. I'd also build a simple index of inline components per project so nothing gets lost between files. The system worked well because we were small and in constant communication. For a larger team or a handoff to another designer, those gaps would matter.
05
The impact
What changed because of it
The most obvious change was speed. Dark mode stopped being a second design pass. New features started from a reliable base instead of a blank file. I stopped rebuilding the same patterns and started spending that time on the problems that actually needed design thinking.
Handoff got noticeably lighter. Based on comparing the time spent on design-to-dev communication across a few features before and after the system, plus direct feedback from engineering, I estimated the system reduced handoff friction by about 25%. Developers liked the dark mode setup enough that they asked me to only share the dark version in handoff files, since they could trust the light version would be correct automatically.
But the less measurable change mattered more. The system built trust. I trusted the foundation, so I didn't have to double-check every screen against every other screen before handing it off. Engineering trusted it because the same components behaved the same way everywhere, and they stopped having to flag inconsistencies or guess at intent.
For a solo designer working across five product surfaces, that trust was the real output. The tokens and components were just how I got there.
Faster design-to-dev handoff
Shared component groups
Shared component groups
Tokens across base and semantic layers
06
Close
A design system built by one person will always reflect the constraints it was built under. This one isn't perfect. The documentation gap is real, and the inline components could be better organized. But it did what it needed to do: it let one designer move fast across an entire product ecosystem without the work falling apart.
The system is still the foundation of every Ticketbro product shipping today.
Still scrolling?
That's a good sign. I'm available for product design roles.
Munich or remote.
Ticketbro
Design System
Ticketbro
Design System
I built the system behind Ticketbro's products so I could stop rebuilding the same patterns and start trusting the foundation.
I built the system behind Ticketbro's products so I could stop rebuilding the same patterns and start trusting the foundation.
Faster handoff
Faster handoff
Faster handoff
Shared components
Shared components
Shared components
Tokens set
Tokens set
Tokens set








Info
Role
Sole Product Designer
Platforms
Mobile, Web, Kiosk
Timeline
Core built Q1 2023, expanded through 2025
Team
1 Designer, Engineers
Tool
Figma
01
Background
Why this needed to exist
By the time I started building the system, Ticketbro's product was already taking shape. Features were shipping, new surfaces were coming, and I was the only designer working across all of them.
The problem wasn't the design quality. It was the process behind it. Every new feature meant rebuilding the same patterns. Every screen needed a light version first, then a manual dark mode pass: duplicating layers, swapping colors by hand, double-checking contrast. It worked, but it was slow, repetitive, and fragile. I'd occasionally overwrite something or introduce a small inconsistency without noticing. That created extra rounds in handoff where developers would flag mismatches or just quietly ignore parts of the design that didn't look intentional.
As the only designer, this wasn't sustainable. The product was growing faster than I could manually maintain consistency across it. So instead of continuing to patch things screen by screen, I stopped and built the foundation properly.
02
The structure
From values to components
I built the system in layers, starting from the most abstract and working up to the most concrete.
The first layer was base tokens: 101 raw values for color, spacing, radius, opacity, and typography. These are the numbers that never change regardless of theme or mode. Primary-500 is a specific blue. Spacing-16 is 16 pixels. No opinions, just values.
The second layer was semantic tokens: 149 mappings that give those values meaning in context. A button's surface color in its default state points to Primary-500 in light mode and Primary-400 in dark mode. The button doesn't know about hex codes. It knows about its own role and state. That separation is what made theming and dark mode manageable instead of manual.


Base values on the left, semantic structure in the middle, button tokens mapped across light and dark on the right.
02
The structure
The third layer was shared components. I built around 50 component groups following an atomic approach. But I was deliberate about what earned a place in the system. If a pattern showed up across multiple features or surfaces, it went into the shared library. If it was specific to one flow, it stayed inline in that project until it proved it belonged somewhere more permanent.
That rule kept the system lean. A bloated library full of one-off components would have been worse than no library at all, especially working alone.

Each shared component included Figma properties for customization. Key components also had short usage descriptions and documented use cases.
50+ shared component groups, each with variants, states, and theme support.

The same foundation reused across customer, provider, kiosk, and other surfaces.
Four themes, each in light and dark mode. Primary colors change, the system holds.
04
The tradeoffs
What I chose not to build
The system was built by one designer for a small team with shifting priorities. That meant making conscious decisions about where to invest time and where to leave things good enough.
I documented the components that needed it most. Ones with multiple variants, non-obvious rules, or behaviors that differed across platforms got short descriptions and usage guidelines. But I didn't reach that level of detail for every component. The simpler, more self-explanatory ones shipped without written guidance and relied on clear naming and consistent structure to communicate intent.
The same pragmatism applied to the library itself. Some components lived inline in specific feature files and never graduated to the shared library. I had a clear rule: if a pattern appeared across multiple features or surfaces, it earned a place in the system. If it didn't, it stayed local. That kept the library honest. But I wish I'd organized those inline components more consistently. When a project ended, the local pieces sometimes stayed scattered across files rather than being cleaned up or promoted.
We also made a mutual decision with engineering not to invest in a full documentation layer at that stage. At our team size and pace, the system could be understood from the file itself. Naming and structure were shaped with engineering input specifically so the system wouldn't need a manual to use. That was the right call for where we were, but it was a tradeoff, not an ideal.
If I were building this again, I'd set a minimum from the start: one line per component explaining when to use it and when not to. I'd also build a simple index of inline components per project so nothing gets lost between files. The system worked well because we were small and in constant communication. For a larger team or a handoff to another designer, those gaps would matter.
05
The impact
What changed because of it
The most obvious change was speed. Dark mode stopped being a second design pass. New features started from a reliable base instead of a blank file. I stopped rebuilding the same patterns and started spending that time on the problems that actually needed design thinking.
Handoff got noticeably lighter. Based on comparing the time spent on design-to-dev communication across a few features before and after the system, plus direct feedback from engineering, I estimated the system reduced handoff friction by about 25%. Developers liked the dark mode setup enough that they asked me to only share the dark version in handoff files, since they could trust the light version would be correct automatically.
But the less measurable change mattered more. The system built trust. I trusted the foundation, so I didn't have to double-check every screen against every other screen before handing it off. Engineering trusted it because the same components behaved the same way everywhere, and they stopped having to flag inconsistencies or guess at intent.
For a solo designer working across five product surfaces, that trust was the real output. The tokens and components were just how I got there.
Faster design-to-dev handoff
Shared component groups
Shared component groups
Tokens across base and semantic layers
06
Close
A design system built by one person will always reflect the constraints it was built under. This one isn't perfect. The documentation gap is real, and the inline components could be better organized. But it did what it needed to do: it let one designer move fast across an entire product ecosystem without the work falling apart.
The system is still the foundation of every Ticketbro product shipping today.
Still scrolling?
That's a good sign. I'm available for product design roles.
Munich or remote.
