STUBHUB ANNOTATIONS
Accessibility Annotations for Developer Handoff
Accessibility is a design deliverable, not a developer guess
When designers don't specify accessibility intent, developers fill the gap — and they fill it wrong.
StubHub's mobile checkout flow is built. It works for sighted mouse users. But across six screens of the purchase path, screen reader users get partial labels, keyboard users lose focus mid-flow, and color-blind users miss urgency cues entirely.
None of these are developer mistakes. They are design specification gaps. The icons were never marked decorative or meaningful. The buttons were never given accessible names. The error messages were never tied to their fields. Every issue traces back to a missing line in the design handoff.
This project annotates ten of those gaps, alongside what should have been specified before any code was written.
// WHAT THE ANNOTATIONS COVER
- Six screens across the StubHub event purchase flow on iOS
- Ten distinct accessibility failures, each mapped to a WCAG POUR principle
- Three layers per annotation: the user impact, the design specification gap, and the fix
- Patterns that recur across the flow: icons without intent, color-only meaning, missing focus management
- Design-time deliverables that would have prevented every issue documented
Three layers per annotation
Each annotation follows the same three-block structure. The pattern forces every gap to be examined from the user, the designer, and the developer perspective, so the fix isn't just code. It's a specification the design system should have carried from the start.
The Problem
What the user actually experiences. Screen reader silence, keyboard traps, missing context: the failure described from the user's seat, not the inspector panel.
What Should Have Been Explicit
The design specification gap. What the designer needed to mark up at design time: labels, roles, focus order, error semantics, so the developer was never guessing.
The A11Y Fix
The remediation a developer can implement directly: WCAG-aligned attributes, semantic HTML, focus management, and accessible names with full context.
// POUR PRINCIPLES TOUCHED ACROSS THE FLOW
The annotated whiteboard
The full annotation set lives on a Canva whiteboard, where each StubHub screen is marked up in place using the three-layer structure described above. The text findings below distill what's visually annotated here — but the whiteboard is the deliverable a developer would actually receive at handoff.
// CANVA WHITEBOARD · 6 SCREENS · 10 ANNOTATIONS
▶ Open whiteboard in Canva ↗Ten gaps across the purchase flow
ANNOTATIONS
AUDITED
TOUCHED
-
PR
Search Field Missing Persistent Label
PROBLEMScreen reader users hear no label when landing on the search field because the only text is a placeholder that disappears on typing.
SHOULD HAVE BEEN EXPLICITThe design must specify a persistent visible label associated with the search input. Placeholder text is not a label.
A11Y FIXEach search field must have a persistent visible label associated with the input. For example: a
labelelement reading "Search" placed above the input and linked viafor/id. Placeholder text alone is not sufficient. -
P
Decorative vs Meaningful Icon Not Specified
PROBLEMScreen reader users get no description of the ticket icon because the attribute points to
titleanddescelements that do not exist in the code.SHOULD HAVE BEEN EXPLICITThe design must specify whether this icon is decorative or meaningful. If meaningful, the exact accessible label text must be provided. Without that, the developer attempted accessibility but did so incorrectly.
A11Y FIXIf decorative, hide it from screen readers entirely. If meaningful, give it an accessible name. For example: a
titleelement inside the SVG with a description like "Ticket price icon" so screen readers can identify it. -
U
Continue Button Missing Context
PROBLEMScreen reader users hear only "Continue" with no indication that this button acknowledges a fee disclosure or where it navigates next.
SHOULD HAVE BEEN EXPLICITThe design must specify a descriptive accessible name for every button that reflects its purpose. "Continue" alone is not sufficient when the action has a specific meaning in context.
A11Y FIXThe button's accessible name must include its purpose. For example: "Continue to event tickets that include all fees." The visible "Continue" label can remain, but the accessible name must carry full context.
-
U
Ticket Price Button Missing Event Context
PROBLEMScreen reader users navigating by button hear "From $247" repeated for every event, with no indication of which event the button applies to.
SHOULD HAVE BEEN EXPLICITEvery repeated action button needs a unique accessible name that includes the event it acts on. A hover tooltip was designed for context, but tooltips are only available to mouse users, so keyboard and touch users never see it. Context that exists for some users must be available to all.
A11Y FIXEach ticket button needs an accessible name that includes the event. For example:
aria-label="Get tickets for Qatar vs Switzerland, June 13, Levi's Stadium, from $247". The visible label "From $247" can remain. -
UR
Status Badges Missing Context
PROBLEMScreen reader users hear "Hottest event" and "Best value" with no indication of what criteria determine these labels or what they mean in the context of buying tickets.
SHOULD HAVE BEEN EXPLICITThe design must specify the full accessible name for every status badge, not just the visible shorthand, plus the correct role for each badge type. The developer used
role="term"(intended for glossary definitions, not status indicators) and badge icons were left unnamed.A11Y FIXEach badge needs an accessible name that includes context. For example:
aria-label="Hottest event: high demand, prices may increase". Mark badge iconsaria-hidden="true"since the text label conveys the meaning. Replacerole="term"with an appropriate status role. -
UR
Modal Title Missing Heading Structure
PROBLEMScreen reader users navigating by headings cannot find or identify the modal's purpose because "How many tickets?" is styled visually as a heading but coded as a plain
divwith no heading role.SHOULD HAVE BEEN EXPLICITEvery modal needs a defined heading level specified in the design. "How many tickets?" is the title of this modal and should have been annotated as an H1 or H2. Without that, the developer styled it visually but never marked it as a real heading.
A11Y FIXMark "How many tickets?" with an actual
h1orh2element inside the modal so screen reader users can identify the modal's purpose when navigating by headings. -
P
Color Used to Convey Urgency
PROBLEMScreen reader users and users who cannot perceive color miss the urgency of "4 tickets sold for this event" because the message relies on pink text and a fire emoji to communicate importance.
SHOULD HAVE BEEN EXPLICITThe design must specify that urgency or emphasis cannot be conveyed through color or emoji alone. Any message requiring user attention must be marked up so its importance is communicated without relying on visual styling.
A11Y FIXThe urgency message must be marked up so screen readers announce it automatically when it appears. The fire emoji needs an accessible name or must be hidden from screen readers if the surrounding text already conveys urgency.
-
O
Auto-Appearing Modal Missing Focus Management
PROBLEMKeyboard users lose their place when this modal appears automatically mid-purchase flow because focus is not moved to the modal, and the triggering element is not defined.
SHOULD HAVE BEEN EXPLICITThe design must specify that any modal appearing automatically must immediately receive focus when it opens. Without this, the developer had no guidance on focus behavior, leaving keyboard users stranded when the modal appears unexpectedly.
A11Y FIXWhen this modal opens automatically, focus must move immediately to the first interactive element or the modal heading. Focus should land on the "Continue" button or "Hey there!" heading on open, and return to the triggering element on close.
-
PU
Error State Not Announced to Screen Readers
PROBLEMThe error message "Please enter a valid email address" is visible as red text but is not announced to screen reader users. It has no programmatic connection to the input field and no live announcement role.
SHOULD HAVE BEEN EXPLICITThe design must specify that the error message requires a programmatic connection to its field, not just visual placement near it. Red color and red border alone cannot communicate an error state to users who cannot perceive color.
A11Y FIXThe email field must be marked invalid when an error occurs, and the error message must be announced automatically when it appears. The message must be associated with the input so screen readers connect the two. Red border and red text alone are not sufficient.
-
UO
Disabled Button Provides No Explanation
PROBLEMKeyboard users tab to the "Continue" button and receive no information about why it is disabled or what action is needed to enable it. They are left with no path forward.
SHOULD HAVE BEEN EXPLICITThe design must specify what conditions disable a button and what message communicates that state to all users. A visually greyed-out button is not sufficient. The reason for the disabled state must be defined at design time.
A11Y FIXThe disabled Continue button must communicate why it is unavailable to all users. For example: "Continue is unavailable until a valid email address is entered." That way, keyboard and screen reader users understand what action is needed.
Four failure modes, recurring
The ten annotations are not ten unrelated bugs. They cluster into four design-time omissions that repeat across the flow. Naming the patterns matters more than fixing one instance, because a pattern fix scales.
PATTERN 01
Icons without intent
Icons appear throughout the flow with no design-time decision about whether they are decorative or meaningful. Developers guess — sometimes hiding important icons, sometimes labeling decorative ones. Every icon needs that flag set in the design file.
↳ AA #2 · AA #5 · AA #7
PATTERN 02
Color carrying the meaning alone
Urgency, error states, and disabled states all rely on color as the only signal. WCAG 1.4.1 — Use of Color — is violated repeatedly. Every state change needs a non-color companion: text, icon shape, programmatic role, or announcement.
↳ AA #7 · AA #9 · AA #10
PATTERN 03
Visible labels that aren't accessible names
"Continue", "From $247", "Hottest event" — short visible labels work for sighted users with full screen context, but strip out everything a screen reader needs to disambiguate. The accessible name must carry the full context the visual layout implies.
↳ AA #1 · AA #3 · AA #4 · AA #5
PATTERN 04
Focus and structure left undefined
Modal headings, auto-appearing dialogs, and disabled-state messaging all skip the keyboard and assistive tech path. Focus management and heading structure are not afterthoughts — they are first-class design specifications, on equal footing with layout and color.
↳ AA #6 · AA #8 · AA #10
Design-time deliverables that close the gap
Add an a11y annotation layer to the Figma component library
Every interactive component in the design system should ship with its accessible name pattern, role, focus order, and decorative-vs-meaningful flag visible in the file. Annotations are not extra work — they are the spec. If a component cannot be annotated, it cannot ship.
Define an "accessible name" requirement on every button and badge token
Tokens for buttons, badges, and status indicators must include both the visible label and the accessible name as separate fields. The pattern of "Continue", "From $247", and "Hottest event" repeats across the flow because the design system never separated the two. Make it impossible to forget.
Specify focus behavior for every modal and dialog at design time
Auto-appearing modals, success states, and error dialogs need a focus-management spec attached to the artboard: where focus lands on open, where it returns on close, what gets the heading role. Developers should not be inferring this from screenshots.
Pair every color-coded state with a non-color signal in the spec
Disabled states, error states, urgency cues, and status indicators must carry a second channel — text, icon shape, role, or live region — defined at design time. WCAG 1.4.1 cannot be remediated in QA. It has to be designed in.
The fix isn't code. It's the handoff.
"Every accessibility failure I annotated traced back to a missing line in the design spec. Developers were not being lazy — they were being asked to invent semantics that the design file should have carried. Accessibility is not a remediation phase. It is a design deliverable."
— Stacy Tomasi · UX 60504 Accessibility & Universal Design · Spring 2026