Alex Savchuk

Terra Design System

Designing, building and operationalizing an in-house design system for an established B2B webapp.

When I first joined Ninety as its sole product designer, the app didn't have a design system. What it had was mostly out-of-the box Material design, pieced together by engineers over the course of a few years. It got the job done, but with the company and the brand growing, its was clear we needed something a bit more scalable. During my first two quarters with the company, I worked on standing up Ninety's first UI kit with an outside agency. Then, in the summer of 2022, Ninety hired a creative director and contracted a firm to undergo a holistic organizational rebrand. We were moving away from our overt affiliation with EOS™, and forging ahead on our own. This was the cue I needed to ditch the original UI kit and start fresh. I'd built custom design systems myself, and I had additional designer support en route – I was convinced we'd have no issues there. The bigger challenge was engineering – how would we go about building out an entirely new component library? Where would it live, and did we even have the resources to take this on?


Luckily, I'd spent my first half-year at the company evangelizing Storybook to the engineering org. For those not familiar, Storybook is a workshop for building UI components and pages in isolation. The potential ROI of housing components in Storybook resonated with engineering leadership, and with the announcement of work on a new design system, I had a number of lead engineers who were willing and eager to take on the Storybook effort in parallel. We were in business!

First Steps

Having internalized Brad Frost’s Atomic Design methodology from previous design system work, I knew I wanted to move full-tilt with applying the principles yet again. The approach makes sense in almost any design context, because it accounts for the smallest atomic component (quarks or tokens) to the largest (organisms, layouts and pages). Some design kits stop at atoms and molecules, and don’t foray into systemizing anything beyond that. While it was too early to tell how far we’d take Ninety’s component library, I’d previously seen a lot of value in housing pages in Storybook for the purposes of QA’ing niche pages that were otherwise hard to access in the wild. Who’s to say we couldn’t house entire pages in Storybook in the future? With that in mind, it made sense to use a system that could be as narrow or as broad as we needed.


At this point I already had one designer on my team, so one of our first joint projects was to define a token system. This included a color palette, typography and an icon library.


With the color palette, we faced an interesting problem – Ninety users have historically been able to define a custom primary color in the UI, which then resonates across their entire interface (historically, this had actually been two colors, but I made the decision to consolidate it to one for predictability and accessibility purposes). It wasn’t something we could just take away: our customers loved it. In all honesty, from a brand and positioning standpoint, I loved it too. Ideally, Ninety wouldn’t just another tool in a company’s toolkit – rather, it would be the digital backbone of the company. From a design perspective, it was a welcome challenge. While we couldn’t predict what color a customer would use, it was also an opportunity to not over-rely on color and instead bank on other Gestalt principles like contrast and whitespace to create a clear information hierarchy. Aside from the company’s custom brand color and some semantic coloring, the rest of the palette would be largely neutral.


From an engineering standpoint, I encouraged devs to define the color palette as HSL. The nice thing about HSL (in contrast to RGB or hex, which is what the codebase had previously used) is that it allowed for easier programmatic color manipulation. By changing the L (lightness) of a given hue / saturation, we could make any color appear lighter or darker in a very predictable way. This meant that we could ingest the company’s brand color and then generate lighter and darker variants for things like hover and focus states.

A sample color palette showcasing HSL color codes.

With the color system in place, we moved on to typography. The new company style guide had defined Poppins as our main font across our marketing materials. While I still wanted to retain Poppins for titles and headings, I knew that we’d need a different font for in-app body text. Our app contains a lot of tables and forms where users input custom strings for things like item names, descriptions, etc. Given that we didn’t (and still don’t) have a native mobile app, our desktop app needed to be as responsive as possible for a variety of viewports. Poppins, while it looked great, had a character width that was unfortunately a little too large for our needs. We needed a font that had a much narrower footprint.


I set up a font evaluation criteria that included things like appearance (how good the font looks on-screen, across a variety of weights and styles, across a range of contexts, and how it looks when paired with Poppins), tone (how the font ‘feels’ – is it too strict/utilitarian? is it too playful?), and most importantly, footprint. I set up the criteria in Figma and worked with my other designer to test 7-10 fonts that were deemed industry standard. In the end, we decided that Nunito Sans struck the best balance across all criteria.

A sample font evaluation, showing three out of seven semifinalists.

Finally, we came to iconography. Our existing app used Material icons which, while utilitarian, unfortunately don’t win many style points. I decided that if we’re redoing the system anyway, we should go all in and find a new icon library. While I’d used Font Awesome repeatedly in the past (and loved it), I wanted something a little budget-friendlier and rougher around the edges (just like Ninety, and most of the small businesses that fall into our ICP). We also knew we didn’t want to go in-house, since our creative team at the time consisted of only two people, and I definitely didn’t want product designers spending a year designing custom icons. We ended up landing on Phosphor icons – a great library by Helena Zhang and Tobias Fried that combines recognizability with a distinctive look-and-feel.


With colors, typefaces and icons in place, we now had the core of our design system. We ended up undergoing a few additional related efforts on both the design and engineering side (color consolidation, icon audit, etc), but those are more boring tales for a more boring time. We’d also eventually add spacing, radius and elevation tokens.

Scaling

Now that we had our tokens, we had to design pretty much everything else. I knew right away that forms and inputs would be incredibly important – most of the engagement our users have with our app involves them filling out a form of some kind, whether it’s two text inputs or two dozen. With that in mind, I did a ton of landscape analysis on comparable design systems in the task / project management space to identify common sizes, patterns and visual trends. Having started my career as an artist, then pivoted to graphic design before landing in UI design, I have always understood that there are very few truly original ideas – and in the realm of product design, an original idea is often not a good thing. Imitating what’s already out there, and repurposing it to work for your problem, is almost always the best approach for yourself, the business, and the user. You save yourself a major headache, the business saves a ton of money by shipping designs faster, and the user benefits because your patterns are more recognizable, learnable and repeatable than a bespoke one ever would have been.

A birds-eye view of part of the landscape analysis.

In the end, no decision made within the design system was arbitrary. Why are most of our inputs 36px? It’s smack dab in the middle of the industry average of 32px-40px, and allows us to stack plenty of inputs within the average viewport without being overbearing. Why did we move away from Material’s default floating labels above inputs? Better accessibility and scannability. Why is our typical border-radius 4px instead of being softer? We get to the point, but we’re not squares. If you want to see more of our design system, and how the product team applied it to both legacy and net new features, check out Ninety.io.

Building

Designing a brand-new component library that can fit the needs of your entire legacy app, while also accommodating potential future needs, is no small feat in and of itself. Actually operationalizing that custom component library is an entirely different beast. As mentioned earlier, the engineering team had taken on a parallel effort to stand up Storybook. Because our feature pods were still dedicated to net new feature work, we faced a bit of a velocity challenge. Storybook was a part-time job for everyone involved, and we couldn't get by with just a few folks devoting a few hours a week to it. Our first approach was to try and democratize the component library – all feature pods, if they worked in the new design system, would be responsible for adding components to Storybook, and documenting them accordingly. We tried this for about two quarters, and needless to say, it did not go well.


While we did manage to expand our component library, it came at a cost. The average pod engineer was reluctant to learn a very specialized skillset for a one-off project like this – and if they did learn it and build a component in Storybook, they'd invariably end up introducing tech debt along the way, because the component and/or corresponding documentation was not put together in a way that was consistent with other engineers. Monitoring the pulse across all pods, I started to see the writing on the wall – Storybook was being perceived as a blocker, and engineers and PMs didn't want to spend time in it. This was bad news for design thinking across the organization. We couldn't continue like this – ideally, we'd have engineers that were dedicated to building out Storybook and all our custom components in a consistent way, documenting them, and shepherding the rollout of those components across the entire organization. So far, we'd been able to get away with using our existing resources, but it was time to ask senior leadership for additional support. Since cross-functional stakeholders are typically in the room for these decisions, I knew that the engineering piece wasn't enough – I had to sell a vision.

The Vision

The pyramid model of the Ninety design vision.

In distilling a design vision for leadership, I leaned on the tried and true pyramid model. We see the pyramid motif repeatedly both inside and outside the digital product space (for example, the Hierarchy of User Needs popularized by Aarron Walter, which in and of itself is a spinoff of Maslow's pyramid), and for good reason – it's a great way to highlight the importance of baseline, foundational needs that should be met before the focus shifts to more elevated needs. In the case of Ninety, I crafted a three-tier pyramid, aligning to three distinct iterations of the app. The design system (and in parallel, the app-wide redesign) would be Ninety's vehicle for climbing the pyramid.


1. Adopt:

This stage is characterized by utilitarianism. Small businesses can run Ninety in a “digital pen and paper” format in a predictable, error-free way. However, users are not able to take advantage of a lot of the features present in other modern webapps. The user-to-app transaction is one sided: users provide the interaction, without getting equal or greater value in return. A symptom of this stage is a lot of user time being spent on menial tasks.


1.5. Engage:

This stage sees us building beyond “digital pen and paper” and offering table-stakes features on par with other modern webapps. The user-to-app transaction begins to equalize: a symptom of this stage is users spending less time on meaningless engagement and more time on tasks that provide value to them and their business. The focus is less on tools, and more on workflows – however, the information hierarchy remains a limiting factor.


2. Scale:

At this stage, we look beyond small businesses and build our app to scale into the medium and enterprise space. We are no longer limited by a tool-centric hierarchy, focusing instead on teams, people and JTBD (workflows). Instead of education being a prerequisite, we offer point solutions that serve as gateways, and subsequently prove the value of Ninety to all tiers of the organization through everboarding and progressive disclosure.


Ninety was trying to operate in the 1.5 ('Engage') space, but we still had lingering issues with performance and predictability in the 1.0 space. In order to move us through the 'Engage' tier, we would have to shore up customer pain points at the foundational level, while also making improvements to the user experience, improving workflows and reducing time to value. From the customer perspective, there should be no discernible switch between the tiers: the idea is to move up the pyramid fluidly and iteratively.

Selling the Vision

Selling the vision to leadership was simpler than I anticipated. A brand-new visual language that aligned with our parent brand, coupled with progressive improvements to the user experience, culminating in a design that would allow our product to scale well beyond our IPO was everything leadership could hope for. This was my job, and I was doing it well. The tougher ask was, naturally, the net new: additional engineering resources.


Thankfully, I’d come prepared with data. Based on the number of components we’d built to date, I’d been able to approximate our velocity. If we continued on our current trajectory, we could hope to see our app fully redesigned in four years. This is with all pods allocating some of their bandwidth to the redesign effort, and overall reduced velocity stemming from a large number of engineers needing to learn the niche Storybook skillset. The better option was to onboard two dedicated engineers, which would get us to a redesign in half the time, with the added benefit of allowing all feature pods to maintain their current velocity. Leadership went for it, and I was over the moon – we’d officially operationalized the design system!


It wasn't long before our new talent was onboarded – and the difference in our previous vs. current way of working was night and day. We were finally able to start putting a dent in all the tech and design debt we'd accumulated over the years, and start replacing it with brand-new tokens and components. In doing so, it became painfully obvious that we could no longer refer to this thing as "design system" – we needed a name that would set it apart in the codebase.

Terra

  • Where did the name ‘Terra’ come from? That bit was truly a team effort. A lot of designers, engineers and PMs had been involved in growing our design system and component library, and I wanted to make things a bit more interesting by giving everyone a chance to name it. I put together some guidelines (stay on brand, stick to themes of solidity, growth, foundation, that sort of stuff), and launched a month-long contest where anyone could submit a name idea and receive a $100 gift card if their idea was the finalist. We received about sixty submissions, and in the end it came down to seven finalists.

Mood board for the design system naming contest, and the seven finalists.

  • I got together with my fellow product design team, as well as the core design system team, to debate the merits of the seven options. Everyone, including creative and brand, seemed to gravitate towards Terra as the most representative of both our larger brand and the concept of a design system. And that was that – our baby had a name! All our new custom components would now have the 'terra-' prefix to differentiate them from Material and legacy Ninety components.

Measuring Progress

In selling the new design system to leadership, we’d committed to a two-year goal of having our legacy app completely redesigned. The next step was to figure out how to quantify progress, get a sense of velocity, and course-correct if we felt like we weren’t on track to meet our goal. The interesting thing about measuring a redesign is that it’s not enough to just count how many new components are being used. Some features may not be componentized at all, while others may appear to be ‘redesigned’ but still be old stuff under the hood. It was clear that we needed multiple metrics in addition to one cornerstone metric that we would use to gauge progress.

A visualization of the metrics used to track progress towards a redesigned Ninety.

In operationalizing the redesign, there were three key players: the design team, the design system engineering team, and the market-facing feature pods. The design team creates the designs, and measures progress in two ways: completion of the Figma design system, and adoption of the design system across all active Figma projects and pages. The design system developers then build the components to Figma specs, and document them in Storybook for other developers to pick up as needed. They also transition legacy Material components to new Terra components: this is tracked via completion and adoption metrics in the codebase. Finally, the feature pods are the ones making sure the new designs make their way to customers – whether it’s paving the way with new design language that hasn’t been componentized, or QA’ing the components implemented by the design system engineers.


In that sense, the component library is not a dependency for the redesign; as long as a button looks and behaves like a new Terra button, the user doesn’t care whether or not it’s a reskin of a Material default, or a bespoke Ninety component. I was able to use this to my advantage in creating a formula for the main cornerstone metric we’d use to track progress: Ninety App Redesign.


At the risk of getting too technical, I was able to use engagement data across the entire app to get an understanding of prominent a given page was in the overall user experience. I then subdivided each page into key areas (e.g. sidenav, page title / subtitle, filters bar, page content, details panel, etc) and tracked design progress across each (not started, in progress, or done). The aggregate of this gave me a sense of how far we’d actually redesigned the app from the user’s perspective. Because some pages – like the app’s main dashboard – feature much more prominently in the user experience than others, redesigning those parts of the app gets us much closer to a redesign than, say, changing the notification preferences page inside settings. Case and point – we were able to get to 12% redesigned by just updating the content area of the app’s landing page.

The Road Ahead

The future looks bright for Terra. We are in the midst of an organizational restructure that will hopefully see even more resources committed to design system development, especially when it comes to paying down lingering design debt and progressively rolling our incremental design improvements to our customers. The entire organization is fully committed to seeing the 1.5 version of our app through to the finish line – after that, the sky is the limit.

A preview of the Ninety app in the Terra design system. Check out Ninety.io for more.

Roles

Lead Product Designer

Client

  • Ninety

Timeline

2021-2024

Date

April 2021 – Present