Marcelo Paiva

A man seen from behind holds a pen facing a woman with a bun, near a door.Meant to show: The designer whose concern was struck off the list months before the audit found it. The decision was made then, not at the audit.

Where do accessibility decisions actually get made?

The color that failed our audit was chosen eleven months earlier, in about two seconds.

Listen to this essay

6 min listen · 5 min read · Read by a synthetic voice (af_heart, made with Kokoro), from the essay’s own words.

Picking #8A8A8A for helper text on white takes about two seconds. It's 3.45:1, so it fails WCAG 1.4.3 Contrast (Minimum). And an auditor will find it eleven months later.

By then it's no longer a color. It's a design system change, a migration, four teams and a conversation about timelines.

Ask where accessibility happens in your organization, and you'll probably be given a stage like that one: a review, an audit, a ticket queue, or a phase near the end with a budget attached.

But ask where the decisions happen, and you get a completely different answer. They happen in a design file, months earlier, while somebody picks a gray.

A decision is cheap in the file and expensive at the audit

Here's why the gap between those answers matters. Everything in the design file is cheap, and everything at the late stage is expensive. Yet we've arranged our craft so that almost all the effort goes to the expensive one.

The designer who chose that gray wasn't careless. They were choosing a visual weight, which is a legitimate thing to do, and nothing in their tool said the choice had a second dimension. Nothing in the file said 3.45:1. Nothing said this one excludes people.

I see the same thing every time I look. The designer's values didn't fail. The information was missing, at the exact moment it would have been free.

And who's on the other side of that gray? People with low vision are. So are people with age-related loss of contrast sensitivity, which is most of us eventually, and people reading on a phone in sunlight, which is most of us weekly.

So I resist the urge to file this under "a small group with specific needs". Contrast is the clearest example we have of a requirement that is specific in where it comes from and universal in who it helps. It's the curb cut argument, in a color picker.

The failure also compounds, quietly. One gray becomes a token, the token becomes a component, and the component becomes forty screens. By the time anyone measures it, the decision has been copied so many times that undoing it is a program, not a fix.

The information belongs where the decision is

So to move it, we'd have to put the information where the decision is.

That's why I built the WCAG Plugin for Figma (opens in a new tab). It's free and open source, and it puts WCAG guidance, annotation cards and accessibility utility tokens inside the file where design decisions actually get made.

It isn't a separate checker you have to remember to open, and it isn't a report. The guidance is in the file, at the moment of the choice.

There's a ceiling on that claim, and I'd rather say so. A plugin doesn't make anyone an accessibility practitioner, and I haven't measured whether teams using it ship better interfaces.

What it changes is when the information arrives. And arriving early is the only thing that has ever made this work cheap.

The annotation cards do a second job. They give a designer a way to tell engineering their intent: this is a button not a link, this heading is level two, this control needs a name. And they do it in the place engineering already reads.

A great deal of accessibility is lost in that handoff. Nobody disagreed with anything. The intent was never written down anywhere that lasts.

Where we ask sets what it costs

Where we ask a question sets what it costs.

Think about what opening a separate contrast checker means: leaving the file, switching context, copying two values, reading a result and coming back. That's maybe ninety seconds. It sounds like nothing, but in practice, it works as a wall.

It'll happen for the brand palette. It won't happen for the forty incidental grays chosen in passing. Asked inside the file, though, the same question costs nothing, so it gets asked about all forty.

The checker is equally accurate either way. The only variable is distance, and distance is a property of our tools, not of anybody's diligence.

That goes well beyond color. We pay attention to any quality we care about according to how close the answer sits to the moment of the decision. Put it one context switch away, and it becomes something careful people do sometimes.

Other decisions can move earlier too

The plugin is one example of a general move, and most of the others cost very little.

Contrast ratios can go in the token names or the documentation. If a palette entry is only safe above 18px, say so where someone picking it will read it.

Design review can take four more questions. Ask about keyboard order, screen reader output, how it rearranges itself at 375 pixels and whether this value exists in the system.

Intent can be annotated in the file, not in a document, because the file is what engineering reads: heading levels, landmarks and names for icon-only controls.

The build can fail on contrast, after a report-only period. Measure first, publish the number and let it be uncomfortable. Then tighten. A gate that arrives as an obstacle before it arrives as information gets resented, and worked around.

And name the criterion: 1.4.3 Contrast (Minimum), 1.4.11 Non-text Contrast or 2.4.7 Focus Visible. A number is a shared reference that a colleague can check and an agent can be pointed at.

Everything after the decision is repair. Repair is always worth doing, but it's never as good as having been right when it was free.

Our tools decide when the information arrives, and our tools are ours to change. The design file is where the decisions are, so let's put the numbers there.

About the drawing

The drawing for this piece was generated, not chosen. Hashing the piece’s name fixes one point on the color wheel; the other two follow from it. The same name always gives the same three colors.

#3730ac#9e4646#46914c

How this drawing was made

The line under the drawing marked “Meant to show” is written by a person, not the model. A generated drawing keeps what is large and loses what is small, so the detail that decides who someone is can go missing, and a picture only reaches people who can see it. Where the drawing and that line disagree, the line is the intent.

Or press the left arrow and the right arrow.

An essay

This is an article in a magazine: a drawing at the top, then the essay, read straight down in one column.

From top to bottom

  1. At the top, the site header: my name, which goes home, then links to Writing, Work, Signal, Tools and Resume, then Settings, where you choose the drawings, light or dark, and movement.
  2. The essay’s drawing, with a line under it on what it was meant to show.
  3. The date, the title, and a one-paragraph summary.
  4. A Listen control: play the essay read aloud by a synthetic voice, with buttons to go back or forward 15 seconds, a position slider and a speed choice. It shows how long it takes to listen and to read.
  5. The essay, in sections with their own headings. Some have pictures, videos, lists or diagrams along the way.
  6. About the drawing: how the drawing was made, and a link to more on that.
  7. Links to the newer and older essay. The left and right arrow keys go there too.
  8. At the bottom, the footer: a note on how this site is built, links to Illustrations, Pens, Concepts and Accessibility, this Describe this page button, then GitHub, LinkedIn and email.

What you can do here

Read the essay.