Case 01 · Enterprise Platform · Gov Tech · Design System

OneStop 2.0: bringing order to a 60-flow regulatory platform.

OneStop is the Alberta Energy Regulator's platform for energy and water applications. I mapped how it fit together, designed the flows, built and looked after the design system, and worked with engineering as product owner to get it shipped. The goal was easy to say and hard to do: one consistent, accessible product for two very different groups of people.

Role
Sr UX Consultant · DS Owner · Product Owner
Timeline
Sep 2024 — Jan 2026
Scope
Architecture → Screens → Hand-off
Standard
WCAG 2.1 AA
OneStop operator dashboard: applications table with status, type and summary
Operator dashboard · Every application in one table, with clear status chips and quick filters.

Context

Every energy and water application in Alberta runs through one system.

The Alberta Energy Regulator oversees energy and water development in the province. Companies use OneStop to apply for, change, renew and cancel licences. AER staff use the same system to review those applications and make decisions on them.

OneStop 2.0 was the rebuild. It had to work for two groups with almost opposite needs: operators filling in long, technical applications, and reviewers working through a queue of them every day.

When I joined, the product had been growing for years without a shared foundation. It worked, but it didn't feel like one product. Each flow did the same things in its own slightly different way.

Operator dashboardRebuilt from the components, tokens and grid in the design system.

The challenge

Sixty flows, all solving the same problems differently.

The visual design was the easy part. In a regulatory system, a confusing form can lead to an incorrect filing, so inconsistency carried real risk.

Patterns everywhere

Tables, forms, modals and wizards had been rebuilt dozens of times. Each one was a little different, and none of them were documented.

Two audiences, one app

Operators needed guidance and room to make mistakes. Reviewers needed dense screens they could move through quickly. Both used the same screens.

Policy behind every field

Many fields were tied to legislation or water-volume calculations. A mislabelled input could turn into a compliance issue.

Slow to ship

With nothing shared, a small policy change could spread across many screens and take weeks to rebuild.

Uneven accessibility

Focus order, labels and contrast changed from flow to flow. For a public government service, that's a real barrier.

No single reference

Designs lived in scattered files and engineers interpreted each one on their own, so things slowly drifted apart.

My role

I ended up wearing four hats.

I joined as a senior UX consultant and gradually took on more of the product. These roles overlapped all the time, and a lot of the value came from one person holding all of them.

A

Information architect

I worked out how the platform fit together: how applications, submissions and authorizations relate, how people move between them, and the dynamic-forms engine behind every flow.

B

Product designer

I designed all 60+ flows end to end, including the parts that are easy to skip, like empty states, errors, bulk upload and edge cases.

C

Design system owner

I built the design system and its tokens, kept it up to date, and set up a way for other teams to add to it without splitting it apart.

D

Product owner

I ran the backlog and roadmap, wrote specs, and worked closely with engineers during the build so what shipped matched both the design and the policy.

Research & analysis

First, I needed to understand how it actually worked.

Before designing anything, I talked to both groups of users, went through every flow, and sat down with policy experts to understand the rules behind the fields.

  • Interviews with operators who submit applications and AER staff who review them.
  • Task analysis of each journey, looking for where people got stuck, went in circles or worked around the system.
  • An audit of all 60+ flows, with each issue rated by how serious and how common it was.
  • Service blueprints linking what applicants see to what happens behind the scenes during review.

A few of the issues from the audit

SevFlowIssue
3Water Term LicenceVolume units inconsistent across steps
2AmendmentUnclear what a change replaces
2Pay / SubmitError message doesn't say why
1Bulk uploadNo progress feedback on large files
1Review queueFilters reset on navigation

The same theme kept coming up. People were being asked to keep track of things in their heads that the interface should have handled for them.

Architecture

One foundation for every flow.

What made it manageable was treating OneStop as a set of shared layers instead of 60 separate products.

ProductsOperator portalStaff consoleReporting & analytics
Flows · 60+Water Term LicenceTemporary DiversionAmendmentRenewalCancellationWater TransferReclamationBulk upload
PatternsApplication dashboardDynamic multi-step formReview queueSummary & disclaimerDocument upload
Components · 180+Data tableFilters & searchStepperDrawerModalInputsDate pickerTabsAlertsUpload
FoundationsDesign tokens12-col gridSpacing scaleType scale (Selawik)Colour & contrastIconography

In the middle of it all is a dynamic-forms engine. Every flow is built from the same form pieces, validation rules and review pattern, so when legislation changes, the team updates configuration instead of writing new code.

The screens

I started with the hardest flow.

The Water Term Licence is one of the most complex applications in OneStop. It has many steps, lots of documents and real water-volume calculations. My thinking was that if the system held up here, it would hold up anywhere.

Water applicationSide navigation that stays in place, inline validation, guidance written from the policy, and tables for diversion and use points.

Small decisions that made a big difference

  • The system does the maths. Daily rates are calculated from the annual volume, so operators don't have to work them out by hand.
  • Nothing gets lost. Every step saves automatically. Losing work on a timeout was one of the biggest complaints in the audit.
  • Errors that help. Messages explain what's wrong and how to fix it, using wording that comes from the policy.
  • A chance to check. A summary and disclaimer screen lets operators review everything before it becomes a legal filing.
Submission detailShows where a submission is in review, using the same components set up for reading instead of filling in.
Application wizardFive guided steps: disclaimer, applicant, activity, measurement points and review.
Sign-inWhere everyone starts, and the only place the full-colour AER logo appears.

The design system

One shared design system.

Tokens at the bottom, 180+ documented components on top, and a clear process for adding to it so it stays consistent as it grows. Everything in this section is live, pulled from the real stylesheet rather than screenshots.

Primary ramp

The blue scale isn't a simple light-to-dark ramp. 600 is the main brand blue for headers and page chrome, and 800 is for links, active states and focus. Mixing them up is the quickest way to make a screen look off-brand.

0
50
100
200
300
400
500
600 ★
700
800 ★

Colour tokens & contrast

TokenValueContrast
color.brand.navy#18496DAA · 8.6:1
color.action.primary#066EA8AA · 4.9:1
color.status.success#639144AA · 4.6:1
color.surface.info#E6F1F6—

Type scale · Selawik

Heading 128/36 · Semibold
Heading 222/30 · Semibold
Body — regulatory copy15/24 · Regular
1000 9038 · 3314576613/18 · Numeric

Selawik is used everywhere. It's open source and spaced like Segoe UI. Roboto handles numbers, because authorization IDs need to line up neatly in table columns.

Component inventory

Data tableColumn searchFilter & sorterPaginationTabsDrawerModalPop-confirmDropdownDate pickerInputsRadio & checkboxAlertsNotificationsInfo cardTooltipsTagsUploadStepperBreadcrumbHeader & footerNavigation barAvatar & menu

Documented states

Every component was documented in all of its states, including the ones people tend to forget.

DefaultHoverFocusActiveDisabledLoadingErrorEmptyTruncated

Run like a product

  • Backlog and roadmap. System work was planned alongside feature work and reported on the same way.
  • Contribution process. Teams had a clear way to suggest, review and add patterns without making their own versions.
  • Versioning and docs. Each component had usage notes, states, do's and don'ts, and accessibility guidance.
  • Adoption tracking. We measured how much the system was actually used, so we knew it was paying off.

How hand-off worked

  • One set of tokens. Colour, type, spacing and radius were defined once and exported to CSS, so design and code stayed in sync.
  • Storybook as the reference. Developers built from the documented components, and QA tested against them.
  • Specs and redlines. States, props and accessibility requirements were all annotated.
  • Working side by side. I stayed with engineering through the build and reviewed pull requests against the system.

Accessibility

Accessible from the ground up.

For a government regulator, accessibility is a legal requirement and simply the right thing to do. Instead of fixing 60+ flows one at a time, I built WCAG 2.1 AA into the components themselves, so every flow got it automatically.

Contrast

Every text and background pairing was checked against AA before it shipped.

Focus and keyboard

A clear, consistent focus order through every multi-step flow.

Screen-reader labels

Names and descriptions documented for each component.

Why I made these calls

The reasoning behind the big decisions.

Most of the work above came down to a handful of choices. Here's what I chose and why.

Start with the hardest flow

If the components could handle the Water Term Licence, the simpler flows would mostly follow. Starting with an easy one would have hidden the problems until later, when they cost more to fix.

Fix the parts, not the pages

Sixty flows was too many to fix one at a time, and fixes made that way drift apart again. Fixing the shared pieces once meant every flow got better together.

Put the rules in configuration

Legislation changes. I didn't want every policy update to become a design and development project. Keeping the rules in configuration makes those changes smaller and safer.

Build accessibility into components

Checking 60 flows by hand every release isn't realistic. When it lives in the components, teams get it right by default, even if they aren't accessibility specialists.

Let the system carry the load

The audit showed people losing work and doing calculations on the side. Both are easy for software and stressful for people, so the interface should handle them.

One set of components, two audiences

Instead of designing two apps, I tuned the same components: more guidance for operators, more density for reviewers. One system to maintain, two experiences that fit.

Take on the product owner role

Design decisions kept getting lost between Figma and code. Owning the backlog and working with engineering day to day meant tradeoffs got made in the room, not after release.

The tradeoff: building shared pieces first is slower at the start. With 60 flows still to go, I thought that was worth it.

Outcome

Where it landed.

60+flows now built on one system
180+documented, accessible components
AAWCAG 2.1 built into the tokens
1shared reference for design and engineering

In moderated usability testing, the rebuilt submission flows led to fewer task errors and smoother work for operators. The bigger change was in how the team works. Policy updates now go through configuration and shared components instead of one-off rebuilds, so AER can ship faster, and consistency and accessibility come built in.

Once the table, the form and the wizard are solved properly, and someone owns them, teams can spend their time on the regulation instead of rebuilding the same screens. — What I took away from OneStop 2.0

Looking back

Where AI could have made this faster.

Regulators can't hand applicant data to an AI tool, and they shouldn't. That rules out the obvious uses. But a lot of this project's slowest work didn't need any sensitive data at all.

Legislation is public. Design files, component specs and audit notes aren't personal data. Test data can be made up. That's where I'd use AI if I did this again: on the work around the data, not the data itself.

The ground rules I'd set

  • No real applicant data, ever. Only public documents, design files and made-up test data go in.
  • Approved tools only. An enterprise or privately hosted model that doesn't train on what you give it.
  • Remove names first. Research notes get de-identified before AI helps summarize them.
  • People make the call. AI drafts. Policy experts, designers and engineers decide.

Where it would have saved the most time

TaskHow AI could helpWhat it needs
Plain-language copyTurn legal wording into help text and error messages people can actually followPublic legislation
Auditing 60+ flowsCompare screens and flag inconsistent tables, forms and labels before a person reviews themDesign files
Accessibility checksCatch contrast problems, missing labels and focus order issues across every flowDesign files, code
Research synthesisGroup interview notes into themes once names and identifying details are removedDe-identified notes
Test and prototype dataGenerate realistic but fake licences, volumes and well points for prototypes and testingNothing real
Component docs and specsDraft usage notes, states and hand-off specs from the design systemDesign system
PrototypingBuild clickable prototypes from the real components, so ideas get tested in days, not weeksDesign system