Case Study · Design Leadership · Accessibility

Accessibility at Scale

Accessibility was not on our roadmap. Customer asks kept arriving anyway. I put my hand up to own it.

Over two years I turned scattered requests into a funded, phased program: selected an audit vendor, mapped the product so nothing would be missed, and phased remediation by audience, customer-facing surfaces first, then CSM, then admin, fixing at the component level as we went. It ended with a VPAT, a design system running one version instead of several, and accessibility that was no longer a fire drill.

My role
I initiated the program and owned it end to end: vendor selection and enablement, audit scoping, finding triage, phased execution, design-system alignment, remediation specification, and customer communication.
Worked across
  • Product Management
  • Engineering & QA
  • External accessibility vendor
  • Customer Success & Support
  • Leadership
Outcome
  • VPAT documentation obtained
  • High-ARR account retained
  • Critical violations reduced on customer-facing surfaces
  • Components consolidated to one accessible version
The moment it became real

The asks came in from everywhere

Ideas posted in the customer community. Account teams forwarding contrast complaints. Slack messages from sales during evaluations, asking about the controls our VPAT marked as “partially supports,” because a prospect had asked.

Each one was small enough to handle on its own. That was the problem. Nobody was counting them, so nobody could see that we were walking into enterprise evaluations without a credible answer, and that no one owned the gap.

I decided to.

Community idea titled 'Enhance accessibility in reports (color contrast)' from a VIP customer, asking the system to auto-switch font color based on background so dark text isn't shown on dark backgrounds.
A VIP customer idea: reports showing dark text on dark backgrounds.
Community idea titled 'Improve Accessibility for Gainsight CS', posted on behalf of a customer reporting that grey text on white is hard to read and small text is challenging, requesting per-user accessibility options.
Another, on behalf of a customer: low-contrast grey text and small type.
Slack message tagging Siva Kiran Yellapragada asking whether there are plans to improve support for functions marked as 'partially supports', because a customer evaluating CS is asking in response to the audit report.
A direct Slack ask: an evaluating customer questioning "partially supports" findings.
Making it a funded initiative

Making it a funded program

I took the pattern to leadership. This was not a backlog of UI bugs. It was a procurement blocker with a growing tail, and it would only get more expensive to fix the longer the product kept shipping on top of it.

I asked for three things: budget, an external audit partner, and a definition of done we could actually be held to. We settled on WCAG 2.1 AA, with the VPAT as the tangible deliverable.

That turned accessibility from something everyone agreed was important into something that had an owner, a scope, and a date.

  1. Secured executive commitment

    Made the case to leadership directly, so accessibility became a funded, owned initiative rather than a side effort. Everything downstream depended on that mandate.

  2. Shaped the investment case and the bar

    Helped build the budget case and defined what “done” meant: conformance against WCAG 2.1 AA, with the VPAT as the deliverable that proved it.

  3. Owned it end to end

    Drove the program across product, engineering, QA, and customer success, from a cold start through execution, governance, and customer communication.

A leadership decision

Choosing the vendor

I spoke to several accessibility vendors before selecting one.

Most could run a checklist and return a list of violations. That was not the hard part. Our product changes behaviour based on role, permissions, and tenant configuration, so the same screen can look correct for one user and be unusable for another. A vendor who could not navigate that would either miss real failures or report failures that were not real.

I chose the partner who could tell the difference, and who could test across assistive technologies, browsers, and operating systems on a product of this size.

Removing the biggest audit risk

Making sure no screen was missed

The risk with a platform this large is that the audit only covers what the vendor happens to find.

So before testing began, I built the product architecture in Excel: every module, every page and feature, the classification of each element, and the flows and states that mattered. Then I recorded video walkthroughs so the vendor understood not just where a screen was, but what it was for and how customers actually used it.

It was unglamorous work. It was also the reason the audit came back with coverage we could trust, and the reason we never had to argue about scope halfway through.

  1. Screen-by-screen flow documentation

    Mapped every in-scope surface so findings landed against a concrete screen and state, not an abstract rule.

  2. Feature walkthrough recordings

    Recorded flows and business context so the vendor understood the why behind each screen, not just the markup.

Excel workbook mapping the product architecture: modules, pages and features, element classifications, and the flows and states in scope for the accessibility audit.
Feature mapping: every screen documented before testing began, so audit coverage was a decision rather than an accident.
The decision

Three ways to sequence two years of work

Once the audit scope was clear, the sequencing question was the real decision. Three options were on the table, and each closed off something.

What we gave up. We phased by audience: customer-facing surfaces first, then CSM, then admin, fixing the components each phase needed at the component level as we went. Nothing was built at the screen level and redone later; the cost was sequencing, not rework. We prioritized this way to close customer-facing exposure early and have something credible to show the accounts who were asking.

A strategic choice

Fix the risk first, then fix the system

Correcting the entire platform at once would have stalled the roadmap for months. So I sequenced the work by exposure, protecting the surfaces a customer or their end users could see, first.

Phase 1End user

Brand-visible, high-traffic, legally exposed.

  • Survey response pages
  • Emails
  • Email opt-out pages
  • Email inline surveys
Phase 2CSM

Daily operational surfaces.

  • Gainsight Home
  • Timeline & Cockpit
  • Customer 360 & Relationship 360
  • Spaces
Phase 3Administrator

Configuration and foundations.

  • Admin & setup surfaces
  • Completes platform-wide coverage
  • Lower day-to-day exposure

The phased approach let us show measurable progress without paralyzing the roadmap.

Equip teams & make the audit usable

Turning findings into work

The vendor returned findings in a tracker. A tracker is not a plan.

I read every finding. For each one I decided whether it was valid in our product context, whether it duplicated something already covered, whether it needed a design decision before it could be fixed, and whether the right fix was local or belonged at the component level. Where the report was ambiguous, I raised it rather than passing the ambiguity downstream.

What stood out was the pattern behind the findings: the same categories of failure repeating across the platform.

Outlook message with DevTools showing an image whose alt attribute is only image0.jpeg, and an NVDA speech viewer reading it, annotated to provide the correct alt text.
Non-descriptive image names: the image's accessible name was only its filename (“image0.jpeg”), so screen readers announced no useful description.
Accessibility panel showing heading levels that skip, breaking the document outline.
Broken heading hierarchy: levels skipped, so the page outline didn't reflect its structure.
DevTools contrast inspector showing a link color at 2.42:1, failing the WCAG minimum.
Poor contrast ratios: interactive text below the WCAG minimum, here a link at 2.42:1.
Example of vague link text that gives no context out of order, such as repeated generic labels.
Less descriptive links: generic link text that loses meaning out of context.
Survey rating where the screen reader only announces 'You are currently on a text element, inside web content,' giving no rating value or role.
Ambiguous screen-reader output: the rating reads only as a bare text element. No role, no value.
The same survey rating announced as a radio group, but the scale's endpoint labels are not conveyed, so the meaning of the ends is missed out of context.
Even when announced as a radio group, the scale's endpoint labels were missed out of context.
Contrast finding demonstrated in context, not asserted from a checklist.

Clarifying findings before engineering started

Once a module was fully evaluated, I ran a war room with the vendor, design, engineering, and QA before any fix was written. The purpose was to settle open questions in one room, in one hour, rather than across twenty Jira comments over three weeks.

Without that step, engineers would have received the audit as a flat bug list and fixed each item where they found it. Some of those fixes would have been wrong, and most of them would have come back.

The turning point

Phase 2 gave me an opening

Phase 1 taught us something uncomfortable. The same failures kept recurring across different screens because they were not really screen problems.

Design system drift

The same components, dropdowns for example, existed in multiple variations across modules. Each behaved slightly differently and implemented accessibility inconsistently. That realization ultimately shifted the direction of the work: from fixing screens to fixing the system underneath them.

Fixing them screen by screen would have worked, briefly. The debt would have returned the moment someone reused an old component.

CSM-facing modules were also running behind on the design system. So I made the case to leadership that one effort could close two problems: bring the modules up to the current design system version, and make them accessible in the process.

01

Mapped the drift, module by module

My team and I divided the surfaces and captured screenshots of every component discrepancy, screen by screen, to see the true scope of the problem.

02

Pointed engineering to the canonical version

Mapped each discrepancy to the correct design system component, so conformance became a property of the system rather than a per-screen effort.

03

Reviewed weekly, decided by use case

Aligned weekly on use-case-driven decisions so adoption stayed grounded in real product needs.

Less visible than Phase 1. More important.
Canonical components

One accessible version of each

Screenshots of the canonical, conformant components go here.

Reducing ambiguity for engineering

Specifying the behaviour, not just the violation

Audit output tells engineers what is broken. It does not tell them what correct looks like.

So I documented the expected behaviour at the level engineers actually build against: what the screen reader should announce for each control, where focus moves when a modal opens and closes, and what gets announced when one field is invalid versus when five are. PMs reviewed the documentation before handoff.

Engineers stopped inferring accessible behaviour. It was specified.

  • Screen-reader announcement expectations documented per control
  • Modal focus management: entry and exit focus mapping
  • Error announcement specifications for single and multiple invalid states
Annotated Configure Filters dialog specifying error announcements: focus moves to the first invalid field and the screen reader announces the specific error.
Error announcement spec: where focus moves and exactly what the screen reader announces, for single and multiple invalid rows.
Tab order and focus management demonstrated through a complex table and dialog.
Scaling the remediation

Reducing engineering load with AI-assisted fixes

By Phase 2, AI tools were part of how I worked day to day.

After reviewing the findings, I identified the issues that were UI-only: the ones that carried no risk to data integrity and no dependency on other modules. Because the platform is interconnected, that judgement mattered more than the fix itself. Getting it wrong would have broken something else.

For those issues, I wrote the fixes myself using AI tooling. Engineering reviewed them and shipped them through the normal process.

It moved a meaningful volume of repetitive UI remediation off the front-end team's plate, and it let their time go to the fixes that genuinely needed an engineer.

A survey preview validated with a browser accessibility audit reporting passing checks for contrast, permitted ARIA attributes, document title, and lang.
Reviewing a violation against the accessibility standard before writing the fix.
The Configure Filters dialog annotated with a fix note to remove the empty default filter row.
Working through a semantic markup correction for a UI-only issue.
Customer communication & retention

Staying close to the customers

Sequencing customer-facing surfaces first was not only a technical call. It was a retention decision.

Business impact

I kept the accounts who had raised accessibility close while the work was in flight: direct updates, honest progress, and visible movement on the specific issues they had asked about. The VPAT and the public accessibility statement gave them something concrete to point to internally.

At least one high-ARR account that had been tracking this stayed.

Retention playbook
  • Customer-facing surfaces sequenced first
  • Direct line to high-ARR stakeholders
  • Regular, credible progress updates
  • VPAT and public statement as proof points
What actually changed

What changed

Before
  • Accessibility was reactive and unowned
  • The same components existed in multiple versions
  • Audit findings arrived as a flat bug list
  • Engineers inferred accessible behaviour
  • No enterprise-ready proof
After
  • A funded program with an owner and a definition of done
  • One accessible version of each, adopted across modules
  • Findings triaged, clarified, and specified before handoff
  • Behaviour documented per control
  • VPAT obtained and a public accessibility statement live
VPAT
Documentation obtained
Enterprise-ready proof
0
Risk-based phases
End user → CSM → Admin
0
High-ARR account retained
Churn prevented
Leadership reflection

What I would do differently

The program worked, but it started later than it should have. The signals were there for a year before anyone, including me, treated them as one problem instead of many small ones.

Unowned work does not announce itself. It arrives as a series of manageable requests, and it stays invisible until someone decides to count them.

Interested in working together?

I lead it hands-on, from risk-based prioritization to component governance and the tooling that keeps it from regressing.

Get in touch