Sandbox full design dossier
A scalable design system created for PHPSandbox to unify an engineering-led product, improve collaboration between design and development, and establish the visual foundation for an ecosystem of developer tools.
Building the foundation
When I joined PHPSandbox as the founding designer, I wasn’t joining a company that wanted to build a single product. The online PHP IDE was only the beginning. The broader vision was to create an ecosystem of browser-based tools that would let PHP developers build, test, and collaborate entirely online, without installing software on their machines. Alongside the IDE, the roadmap already included notebooks, multiplayer collaboration, GitHub integration, dependency management, and other productivity tools.
As exciting as that vision was, it introduced a challenge. Every new product would inevitably reuse the same interface patterns, buttons, forms, navigation, cards, modals, tables, badges, and dozens of other components. Without a shared foundation, every team would end up solving the same problems repeatedly, leading to inconsistent experiences, duplicated effort, and growing design debt.
At the time, PHPSandbox had been built by developers, for developers. The focus had understandably been on functionality and shipping features rather than establishing a cohesive product language. Bootstrap components, Tailwind utilities, and custom implementations coexisted throughout the interface, making the product functional but visually inconsistent and increasingly difficult to scale.
Rather than redesigning individual screens as new features emerged, I proposed building a design system first. The goal wasn’t simply to improve consistency. It was to establish a shared language that both designers and engineers could rely on as the company expanded its product ecosystem.
My role
Founding Product Designer. I led the strategy, design, documentation, and implementation of Sandbox, the design system that became the foundation for PHPSandbox’s products. My responsibilities included:
Defining the design system strategy.
Auditing the existing product experience.
Designing foundations, tokens, and reusable components.
Establishing accessibility standards aligned with WCAG.
Collaborating closely with engineering on implementation.
Documenting components and usage guidelines.
Exporting design tokens for engineering consumption.
Project snapshot
Area
Detail
Role
Founding Product Designer
Timeline
3 months
Team
1 designer, 1 frontend engineer, 2 backend engineers, CEO occasionally contributing to frontend
Platform
Web
Documentation
Zeroheight + Figma
Design tool
Figma
Token delivery
JSON export
Accessibility
WCAG-focused
The product solved developers’ problems exceptionally well. What it lacked wasn’t functionality, but a system that could support the company’s ambition to build an ecosystem of developer tools.
Understanding the problem
Before designing a single component, I wanted to understand the product as it existed, not just from a visual perspective, but from the perspective of both developers building it and developers using it. Rather than assuming what needed to change, I conducted a heuristic evaluation of the existing interface. The goal wasn’t to redesign individual screens, but to identify recurring patterns, inconsistencies, and opportunities that could be solved systematically.
Because PHPSandbox had grown as an engineering-led product, the interface reflected years of practical decisions made while shipping features. Bootstrap components, Tailwind utilities, and custom implementations had been introduced over time, resulting in a product that worked well but lacked a consistent visual and interaction language. This audit became the foundation for every design decision that followed.
Inconsistent components
The same interaction was often represented in different ways across the product.
Multiple button styles with different spacing and sizing.
Different border radii across components.
Inconsistent input fields.
Different approaches to cards and containers.
Without a shared component library, every new feature introduced another variation.
No design foundations
There was no underlying system governing how the interface should be built:
No spacing scale.
No typography hierarchy.
No standardized colour tokens.
No reusable variables.
No consistent naming convention.
As a result, every design and implementation decision became an isolated one.
Design and code were disconnected
The product had been built primarily through engineering decisions. While this enabled the team to move quickly, there wasn’t a shared language between design and development. Developers frequently relied on Bootstrap components, Tailwind utilities, or custom implementations based on the immediate needs of a feature rather than reusable patterns. As the company planned additional developer tools, this approach would become increasingly difficult to maintain.
Accessibility wasn’t built into the foundation
Accessibility wasn’t ignored, but it wasn’t embedded into the product’s building blocks. Focus states, contrast, semantic labelling, keyboard navigation, and reusable accessibility patterns were not standardized, meaning each new feature had to solve these challenges independently. I wanted accessibility to become part of the system itself rather than something considered at the end of a project.
Looking beyond PHPSandbox
I also studied established design systems, not to copy them, but to understand why they worked.
Design system
What I learned
Shopify Polaris
Information architecture, documentation, component organization, and governance.
VS Code
Dense layouts, IDE workflows, theming, and familiar interaction patterns for developers.
Material Design
Accessibility standards, interaction states, and scalable component patterns.
Apple HIG
Clarity, hierarchy, and restraint in interface design.
Ant Design
Enterprise component architecture and complex UI patterns.
Polaris had the greatest influence on how I structured Sandbox, particularly in the organization of components, documentation, and naming conventions. VS Code shaped many of the interaction patterns, because the goal wasn’t to reinvent how developers work, it was to build an environment that felt immediately familiar.
Defining the opportunity
By the end of the discovery phase, the challenge had become much clearer. The problem wasn’t simply inconsistent buttons or spacing.
The real problem was the absence of a shared product language.
Without one, every new feature, and eventually every new product, would continue introducing inconsistency, slowing both design and development. Instead of fixing individual screens, I decided to solve the problem at its source by creating a system that every future product could build upon.
Design principles
Every design system reflects a set of beliefs. Before creating a single component, I wanted to define the principles that every future design decision would be measured against. A design system isn’t simply a collection of reusable components. It’s a decision-making framework. Whenever a new component was introduced, a pattern evolved, or a feature required something unique, I wanted the team to have a clear set of principles to guide those decisions.
Familiar before novel
PHPSandbox is a tool that developers spend hours using every day. The goal wasn’t to reinvent how developer tools should look or behave. Instead, I wanted the experience to feel immediately familiar to developers coming from environments like VS Code or other modern IDEs. Familiar interaction patterns reduce the learning curve, allowing users to focus on writing code rather than learning a new interface. This principle influenced everything from the sidebar structure to navigation, editor layouts, keyboard interactions, and theming. Design should reduce cognitive load, not introduce it.
Design for systems, not screens
Rather than solving individual UI problems as they appeared, every decision was made with reuse in mind. If a pattern appeared repeatedly, or was likely to appear across future products, it deserved to become part of the system instead of being solved independently. This mindset transformed the design process from creating pages to creating building blocks. Instead of asking “how should this page look?”, I started asking “what reusable pattern does this page need?”. This approach allowed the system to grow naturally alongside the product.
Accessibility is a foundation
Accessibility wasn’t treated as a final review before release. It was designed into the system from the beginning. Every component was created with accessibility in mind, including:
Accessible colour contrast.
Visible keyboard focus states.
Semantic naming and labelling.
Predictable keyboard navigation.
Human-readable error messages.
WCAG-compliant interaction patterns.
Embedding accessibility into reusable components meant every future product inherited these improvements automatically instead of having to solve them repeatedly.
Build with engineering, not for engineering
Sandbox was developed in close collaboration with the engineering team. Every significant design decision was discussed before implementation to ensure it aligned with technical constraints, existing workflows, and long-term maintainability. Rather than treating handoff as the end of the design process, implementation became part of it. This collaborative approach also influenced the system architecture: design tokens were managed through Figma Variables and exported as JSON, enabling engineers to consume the same values directly and reducing inconsistencies between design and code. The objective wasn’t pixel-perfect parity, it was a shared language.
Build for tomorrow’s products
The design system wasn’t created because the IDE had become too large. It was created because the company intended to build many more products. Every decision was made with future scalability in mind. From component architecture and token organisation to naming conventions and documentation, Sandbox was designed to support an ecosystem rather than a single application. This meant investing in foundations early so future products could move faster without sacrificing consistency.
Design philosophy
A design system is not successful because it contains hundreds of components. It is successful when it becomes the easiest and most reliable way for teams to build products.
Consistency is a by-product. The real value lies in creating a shared language that helps designers and engineers make better decisions together.
System architecture
Before designing components, I needed to design the system that would support them. One of the biggest lessons I’ve learned is that design systems rarely fail because of poor visual design. They fail because they become difficult to scale. Adding a new component shouldn’t require rethinking the entire system. Designers should know where things belong, engineers should know how they’re implemented, and everyone should speak the same language.
Organizing for scale
I adopted the principles of Atomic Design as the structural foundation of Sandbox. Not because Atomic Design is the only correct methodology, but because it provided a predictable hierarchy that both designers and engineers could understand as the system expanded. The system was organized into three layers:
Foundations, the design decisions that define the visual language, such as colour, typography, spacing, elevation, icons, and radius.
Components, reusable interface elements built from those foundations, including buttons, inputs, cards, badges, navigation, and IDE-specific patterns.
Templates and pages, examples showing how components work together to solve real product problems.
This separation ensured that visual decisions flowed consistently throughout the entire system.
Designing with variables
Rather than defining colours or spacing directly inside components, I built the system using Figma Variables. This made the design system significantly easier to maintain as it evolved. Instead of changing dozens of components individually, updates could be made once and inherited throughout the system. The architecture followed two distinct token layers, flowing from primitive tokens to semantic tokens to components to products.
Primitive tokens defined the raw values used throughout the system, Purple 500, Gray 100, Radius 4, Space 16, Font Size 14. These values never described their purpose. They only represented design decisions.
Semantic tokens described how those values should be used, Primary Background, Surface, Success, Warning, Error, Border Default, Text Secondary.
Separating primitives from semantics meant visual changes could happen without rebuilding the component library. Changing a primary colour, introducing themes, or adjusting brand colours became significantly easier because components referenced semantic meaning rather than fixed values.
Naming components
As the component library grew, consistency became just as important as the components themselves. Every component followed a predictable naming convention inspired by mature systems like Shopify Polaris.
Component
Variants
Button
Primary, Secondary, Ghost, Destructive
Input
Default, Error, Disabled
Badge
Success, Warning, Error
A predictable structure made components easier to find, easier to maintain, and easier for new designers to understand.
Building components with intent
Not every UI element deserved to become a reusable component. A simple rule guided the system:
If a pattern appeared three or more times, or was likely to appear across future products, it became a reusable component.
This prevented the library from becoming bloated while ensuring repeated design problems were solved once instead of repeatedly. The goal wasn’t to create the biggest design system. It was to create the most useful one.
Documentation as part of the system
Documentation wasn’t something added after the design work was complete. It was designed alongside every component. Each component included usage guidelines, variants, states, do’s and don’ts, accessibility considerations, implementation notes, and naming conventions. The system itself lived inside Figma, while broader documentation and usage guidance were maintained in Zeroheight, making it accessible to both designers and engineers.
Preparing for engineering
One of the goals of Sandbox was to reduce the gap between design and implementation. Because the system was built using Figma Variables, tokens could be exported as JSON, allowing engineering to consume the same values that existed in design. This created a shared source of truth across both disciplines. Rather than treating design files as static mockups, the system became something that could actively support implementation.
Designing the foundations
A strong design system isn’t built on components, it is built on decisions. Before designing buttons, inputs, or navigation, I established the visual foundations that every component would inherit. For Sandbox, every foundational decision balanced two priorities: supporting a dense, developer-focused interface, and creating a system that could scale across future products.
Spacing, designing for dense interfaces
Unlike marketing websites or consumer applications, developer tools present a large amount of information within a limited space. Panels, code editors, sidebars, inspectors, and toolbars all compete for screen real estate. Every pixel matters. For this reason, I adopted a 4px spacing scale instead of an 8px-only system. A 4px base unit allowed the interface to remain compact while maintaining a predictable rhythm across layouts and components. Rather than relying on arbitrary values, every spacing decision became a multiple of four: 4, 8, 12, 16, 20, 24, 32, 40, 48, 64.
Designers could create layouts with consistent spacing relationships.
Engineers could implement spacing using a predictable mathematical scale rather than one-off values.
The result was an interface that felt organized without sacrificing information density. The goal wasn’t to make the UI spacious, it was to make it intentional.
Corner radius, precision over personality
The visual language of Sandbox needed to communicate precision. Developer tools are productivity environments rather than marketing experiences, so large rounded corners would have felt overly playful. At the same time, completely square corners can appear harsh and visually rigid. I standardized on a 4px corner radius to strike a balance between these extremes. The subtle radius softened the interface just enough to improve readability while preserving the technical, focused character expected from an IDE.
Typography, choosing type for two different jobs
Not every part of the interface serves the same purpose. The product interface and the code editor solve fundamentally different problems, so they required different typographic solutions. For the application interface, I chose Satoshi because of its modern appearance, strong readability, and versatility across navigation, forms, tables, and general UI. Inside the code editor, I used Fira Code, a typeface designed specifically for programming. Its ligatures, character distinction, and familiarity make long coding sessions easier to read and more comfortable for developers.
I also standardized a 140% line height throughout the system. A larger line height introduced unnecessary vertical spacing in dense layouts, while tighter spacing reduced readability. 140% provided a balance between clarity and efficient use of space, particularly important in an interface where users spend extended periods reading both code and UI.
Colour, building around an existing identity
When I joined PHPSandbox, the brand was already centered around purple. Rather than introducing a new identity, I expanded the existing one into a scalable colour system. Using palette-generation tools as a starting point, I generated shade and tint scales before manually refining them to achieve visual balance across the interface. Manual adjustments ensured colours behaved consistently in real-world UI rather than simply following mathematically generated values.
For semantic colours such as success, warning, and error, I took inspiration from mature systems like Shopify Polaris while adapting them to fit the overall visual language of Sandbox. The objective wasn’t to replicate another system, it was to build one that felt native to PHPSandbox.
Themes, giving developers choice
Developers often spend entire workdays inside their development environment. Over time, many become accustomed to specific themes and visual environments. Rather than offering a single dark mode, I designed multiple dark themes inspired by modern IDEs. This decision wasn’t purely aesthetic. It reduced the friction of switching tools by allowing developers to work in an environment that already felt familiar. The architecture also made future theming significantly easier because colours were managed through semantic tokens instead of hardcoded values.
Consistency through constraints
Consistency isn’t created by repeatedly making the same decision. It’s created by making fewer decisions.
Once spacing, typography, colours, radius, and themes were standardized, every future component inherited those choices automatically. Instead of debating visual details every time a new feature was designed, the team could focus on solving user problems. The foundations became the guardrails that enabled faster and more consistent design.
Designing the component library
Components are the visible output of a design system, but they are only valuable when they solve recurring problems. Rather than designing a large library for the sake of completeness, I focused on creating reusable building blocks that reduced duplication, improved consistency, and supported future products. Every component inherited the foundations established in the previous chapter, so components felt cohesive regardless of where they appeared. By the end of the project, Sandbox included more than 22 component categories, each designed with multiple variants, states, and accessibility considerations.
Buttons, designing for different levels of action
Buttons seem simple, but they quickly become one of the most complex components in a design system. PHPSandbox required multiple button patterns, from primary actions to ghost buttons, destructive actions, and buttons with dropdown functionality. The challenge wasn’t designing individual buttons. It was designing a flexible system that supported different use cases without introducing unnecessary variants. Instead of creating a new button for every situation, I established a consistent structure where hierarchy, size, and behaviour were controlled through predictable properties. This reduced visual inconsistency while making implementation significantly easier.
Cards, balancing flexibility with consistency
Cards became one of the most challenging components to design. Different parts of PHPSandbox used cards in different ways, from dashboards and project listings to notebook previews and dependency management. Without a system, these layouts began to diverge visually. Instead of creating entirely different card components, I identified the shared structure across each variation and standardized the parts that remained consistent while allowing controlled flexibility where products needed it. This made cards adaptable without making them unpredictable.
Inputs and search, designing for developer workflows
One of the most interesting design discussions happened around search. Initially, I designed dependency search to display matching packages dynamically as users typed, reducing the effort required to find libraries. During implementation, engineering raised an important edge case: dependency repositories often return a large number of possible matches, making a simple dropdown insufficient. Rather than abandoning the interaction, we collaborated to redesign the experience. The final solution introduced a scrollable results panel that handled larger datasets while maintaining immediate feedback. It was a good reminder that implementation constraints often improve interaction design rather than limit it.
IDE components, designing for specialized workflows
Unlike traditional SaaS products, PHPSandbox included components unique to developer tools. The most significant was the code editor wrapper. This became one of the most iterative parts of the system because different notebook types introduced different interaction patterns. Interactive notebooks supported multiple tabs; non-interactive notebooks did not. Finding a solution that supported both experiences while maintaining consistency required multiple design explorations and close collaboration with engineering. The final design established a flexible wrapper that could support both workflows without making either experience feel compromised.
Badges, designing beyond existing systems
While Sandbox was influenced by systems such as Polaris, not every problem had an existing solution. Badges were one example. PHPSandbox required badge patterns specific to its workflows, making it necessary to design components that reflected the product rather than copying another design system. External systems served as references rather than templates. The final badge component reflected Sandbox’s own visual language while remaining consistent with the rest of the system.
The component I’m most proud of
The code editor became my favourite component because it represented everything the project was trying to achieve. Rather than creating an interface that looked different for the sake of originality, I focused on creating an experience that felt immediately familiar to developers. The result was an editor that borrowed established mental models from modern IDEs while remaining consistent with the overall Sandbox design language. Sometimes good design isn’t about creating something users have never seen before. It’s about making them feel at home from the first interaction.
Component evolution
No component was considered finished after its first iteration. Throughout the project, the component library evolved through:
Engineering feedback.
Product requirements.
Accessibility improvements.
New feature requests.
Real implementation constraints.
The design system wasn’t static. It matured alongside the product. That continuous evolution became one of its greatest strengths.
Design decisions that matter
Throughout the project, I found myself asking the same questions repeatedly:
Can this solve more than one problem?
Will another product eventually need this?
Does this reduce or increase complexity?
Is this intuitive for developers?
Can engineering implement it consistently?
Those questions became more important than any individual component. They shaped the way the entire system evolved.
From design to production
A design system isn’t finished when the Figma file is complete. It’s successful when designers and engineers can use it to build products consistently. One of the biggest goals of Sandbox was to reduce the gap between design and implementation. Rather than treating design as something handed over at the end of a project, I wanted the system itself to become a shared language between design and engineering.
Collaboration from day one
Engineering wasn’t introduced after the design work was complete. They were involved throughout the process. Whenever a new component or interaction was needed, we discussed it before implementation to understand technical constraints, existing product behaviour, and opportunities to simplify the solution. The dependency search experience is the clearest example: what began as a straightforward interaction became a better one after engineering highlighted the challenge of large result sets, and we redesigned it together into a scrollable results panel. Good collaboration often produces better outcomes than working in isolation.
Documentation as a product
I treated documentation as part of the design system rather than something created after the work was complete. Every reusable component included guidance that helped designers and engineers understand not only what to use, but when and how to use it: component purpose, variants, states, usage guidelines, accessibility considerations, naming conventions, and implementation notes. The design system itself lived inside Figma, while broader documentation was maintained in Zeroheight, giving the team a central place to reference the system as it evolved.
Keeping design and code aligned
One of the challenges with many design systems is that the design file and the codebase slowly drift apart. To reduce this risk, I built Sandbox using Figma Variables and structured the token architecture so values could be exported as JSON. This created a shared source of truth for designers and engineers. Instead of manually recreating values during implementation, engineering could work from the same tokens defined in the design system.
Evolving the system
The first version of Sandbox wasn’t intended to be the final version. New components were only added after evaluating whether an existing pattern could be extended first. If the problem genuinely required a new solution, the process was straightforward:
Identify the recurring pattern.
Review whether an existing component could solve it.
Design the component if needed.
Validate the approach with engineering.
Document variants, behaviours, and usage.
Add it to the design system.
This lightweight governance worked well for a small product team while preventing unnecessary duplication. The goal wasn’t to make the library bigger. It was to keep it coherent.
Accessibility in production
Accessibility wasn’t considered complete when the designs passed a contrast checker. It was verified again during implementation:
Reviewing colour contrast using Figma plugins during design.
Testing keyboard-only navigation after implementation.
Verifying logical focus order from left to right and top to bottom.
Ensuring error messages communicated clearly in human language rather than exposing technical system errors.
Embedding these checks into implementation helped ensure accessibility remained part of the product rather than simply part of the design file.
What changed
By moving beyond a traditional handoff process, the design system became more than a collection of reusable assets. It established:
A shared vocabulary between design and engineering.
Consistent implementation patterns.
Faster onboarding for future contributors.
A scalable foundation for additional products.
A repeatable process for introducing new components.
Most importantly, it changed the conversation. Instead of discussing how individual screens should look, the team could focus on solving user problems using a shared set of building blocks.
The biggest lesson
I started the project believing that a design system was primarily a library of reusable components. I finished it understanding that a design system is really an operating model for product teams.
Its greatest value isn’t visual consistency. It’s enabling designers and engineers to make consistent decisions together.
Reflections and lessons learned
When I joined PHPSandbox, my goal was straightforward: introduce consistency into an engineering-led product. Looking back, I realise that consistency was never the destination. It was the outcome. The real value of the project came from creating a shared language that allowed designers and engineers to solve problems together. That shift in perspective has influenced how I approach every product since.
A design system is product infrastructure
Before this project, I viewed design systems primarily as collections of reusable components. Sandbox challenged that assumption. The real work involved establishing principles, defining governance, creating documentation, collaborating with engineering, and building a foundation that could support future products. A button isn’t valuable because it’s reusable. It’s valuable because everyone on the team understands when, why, and how to use it. That shared understanding is what makes a design system successful.
Consistency comes from constraints
One of the biggest lessons I learned was that consistency isn’t achieved by asking designers to make the same decisions repeatedly. It’s achieved by removing unnecessary decisions altogether. Once spacing, typography, colours, tokens, and interaction patterns were established, new components naturally felt like part of the same family. The design system acted as a set of guardrails rather than a set of restrictions. Good systems don’t limit creativity. They protect it from inconsistency.
Collaboration creates better products
Some of the strongest solutions in Sandbox came from conversations rather than sketches. The dependency search redesign is a good example. Instead of defending the original design, we treated the constraint as another design problem to solve. That experience reinforced an important belief: design quality improves when design and engineering work together early, not when they work sequentially.
Not every product needs a design system
One opinion I’ve developed through this project is that not every product should invest in a comprehensive design system. Early-stage startups often move too quickly for a large component library to deliver meaningful value. A design system becomes worthwhile when teams begin solving the same problems repeatedly, supporting multiple products, or working across multiple designers and engineers. The goal should never be to build a design system because mature companies have one. The goal should be to solve the right organisational problems at the right time.
What I would do differently
I would spend more time understanding the company’s long-term product strategy before deciding which components to prioritise, mapping the system more deliberately against future business goals. I would introduce lightweight governance earlier, defining how new components are proposed, reviewed, and maintained as the library grows. And I would establish clearer adoption metrics from the beginning: success shouldn’t only be measured by the number of components created, but by outcomes such as reduced duplication, faster implementation, improved accessibility, and increased consistency across products. These are lessons I now carry into every design system project.
Looking ahead
Sandbox was created for a small engineering-led team building developer tools. The principles behind it, however, extend far beyond this project. Whether designing a design system, a fintech platform, or a healthcare product, my approach remains consistent:
Understand the problem before designing the solution.
Build systems instead of isolated screens.
Collaborate closely with engineering.
Treat accessibility as a requirement, not an enhancement.
Design with the future in mind, while solving today’s problems.
Final thoughts
Looking back, I’m proud of the components we built. But I’m even more proud of the conversations they enabled. Sandbox introduced a common language that helped design and engineering move faster together. It replaced individual design decisions with shared principles, reusable patterns, and a scalable foundation that could support future products.
A successful design system isn’t measured by the number of components it contains. It’s measured by how confidently teams can build with it.
Outcomes and impact
The success of Sandbox wasn’t measured by the number of components it contained. It was measured by whether it became the default way to design and build products at PHPSandbox. Although the system was created over a relatively short period, it immediately changed how new interfaces were designed and discussed. Instead of approaching each feature as a new design problem, the team could build from a shared set of foundations, components, and patterns.
22+
reusable component categories with variants and states.
3
months from audit to adopted system.
4px
base unit for spacing and corner radius.
What changed
Sandbox introduced a structured foundation that the product previously lacked. The project established:
A unified visual language across the platform.
Reusable components that reduced duplicated interface patterns.
Shared design tokens for colours, spacing, typography, and elevation.
Accessibility standards embedded into reusable components.
Consistent naming conventions for both designers and engineers.
Documentation that made the system easier to adopt and maintain.
A better design workflow
Before the design system, creating a new interface often meant making decisions from scratch. After Sandbox, much of that work shifted from creating to composing. Designers could assemble new experiences using established patterns, while engineers could implement them with greater confidence because the visual language remained consistent. This reduced unnecessary discussion around UI details and encouraged conversations about user experience instead.
A stronger engineering partnership
One of the most valuable outcomes wasn’t visual, it was collaborative. Throughout the project, design and engineering developed a shared vocabulary for discussing interface decisions. Questions shifted from “how should this button look?” to “do we already have a pattern for this?”. That small change represented a much larger shift in how the team approached product development. The design system became a reference point for decision-making rather than just a library of assets.
Preparing for growth
Although Sandbox was initially built to support PHPSandbox, it was designed with a broader ambition. The company planned to expand beyond a single browser-based IDE into a wider ecosystem of developer tools. By investing in design foundations early, future products would have a consistent starting point instead of rebuilding common interface patterns from scratch. In that sense, Sandbox wasn’t just a solution for today’s product, it was an investment in tomorrow’s products.
Key deliverables
Area
Outcome
Foundations
Colour, typography, spacing, radius, elevation, iconography.
Token architecture
Primitive and semantic design tokens managed through Figma Variables.
Components
22+ reusable component categories with variants and states.
Accessibility
WCAG-conscious colours, keyboard navigation, focus states, semantic patterns.
Documentation
Component guidance, usage rules, implementation notes, and Zeroheight documentation.
Collaboration
Shared workflow between design and engineering.
Looking back
Sandbox achieved what I originally set out to do. It transformed an engineering-led product with inconsistent interface patterns into one supported by a scalable design foundation. More importantly, it changed the way I think about systems. I no longer see design systems as libraries of components. I see them as tools that help teams make better decisions, collaborate more effectively, and build products with greater confidence.
Closing statement
Every product begins as a collection of features. The best products eventually become collections of thoughtful systems. Sandbox was my first opportunity to build one of those systems from the ground up.
Good interfaces solve today’s problems. Great design systems make tomorrow’s problems easier to solve.