Get a quote
Web Software

When web accessibility becomes a legal requirement: the cost depends on where a colour lives

Keep the brand gold; the costly part is a colour scattered across screens. How many files open to fix a shade, what does the audit miss, and who writes the disproportionate-burden assessment?

Algoriel 16 min read
When web accessibility becomes a legal requirement: the cost depends on where a colour lives
In this article
  1. What accessibility costs is decided by where a colour is written
  2. The same colour is measured again in the dark theme
  3. A control whose only cue is its border is invisible to the audit
  4. When the audit says clean, ask what it did not scan
  5. Why accessibility added later costs more
  6. Disproportionate burden is an assessment you write, not a status you hold
  7. Scope is drawn by where your customer is, not by your address

Web accessibility means a site that works for someone on a screen reader, on the keyboard alone, or with little tolerance for low contrast; the European Accessibility Act lists e-commerce services in its scope. What compliance costs is decided long before the audit, by where a colour was written in the first place. Our audit never matched links styled as buttons, and its clean verdict skipped a low-contrast border it never measured.

What accessibility costs is decided by where a colour is written

A colour in a website lives either inside the component that paints it, or in a definition file the component never touches. The second arrangement puts a structure in between. A raw-value layer holds the shades, written once and never used directly. A semantic layer gives those shades role names. The component asks for a role, never for a value.

A role name describes function, not appearance. Body text, muted text, headings, links, accent and focus ring are separate roles, even when several of them resolve to the same raw shade today. That repetition is not waste; it is a record. Somebody reading the definition file can see where the shade works as text, where it works as a line, where it works as an accent. Appearance changes with theme and with the surface underneath it. Function does not. That is the whole reason the naming follows function.

The practical consequence is short. Correcting a colour means editing a single line in the token definition. No component file is opened, because no component knows the colour exists. Utility classes bind to the name as well, not to the value: the class stays where it is, and the value it resolves to changes underneath it.

You do not need any accessibility knowledge to find out whether your own site has this layer. Ask for one shade to be darkened by a single step and count how many files get opened. If the answer is one file, the layer is there. If the answer is “we need to look first”, the layer is not there, and every contrast decision you take from now on will be priced against the size of that answer.

On a site being built from scratch, putting this layer in is not even a line item. In web development work it happens before the first screen is drawn, and after that nobody touches it again. There is a case where it buys nothing: a set of pages produced once, in a single theme, with a known end date. Adding a layer of indirection there only adds files. The dividing line is lifespan. A store that will be maintained for years and a campaign page do not deserve the same decision.

The same colour is measured again in the dark theme

A theme does not change the role name a component asks for. It changes the value that name resolves to. One attribute on the root element moves the whole page between the light theme and the dark theme, and not a single component file is aware of it. When that value gets settled relative to the first paint is a separate matter, and we wrote about it in building a fast website with Astro.

For accessibility this structure has a blunt consequence. The contrast of a colour pair is measured again in each theme. A pair that clears the threshold on light may fail on dark, and knowing it passed once tells you nothing about the other.

Brand gold is a good illustration. On a light background, gold does not clear the threshold as text. That is not a reason to remove gold from the site; it is a reason to narrow its role. The shade stays in large ornamental marks, thin dividers, icon strokes, and the single accent button in a view. Where words in that colour cannot be avoided, a separate ink token is defined for the job, and anything that has to be read takes the ink instead. In the dark theme the accent role binds to a lighter gold, and the ink token can be set equal to it. Whether text needs its own shade turns out to depend on the theme, but the decision sits in the token file, so no component ever learns about the distinction.

Measurement sometimes changes the decision. The shade chosen for interactive borders cleared the threshold on the light theme. On the raised surface of the dark theme, the same shade fell under it. The dark theme now binds borders to a shade one step lighter. The direction of emphasis flips too: on light, hovering a control makes its border darker than at rest; on dark, lighter.

A token can carry “text” in its name without being meant for text. It sits below the thresholds in the light theme and in the dark theme, deliberately. Its legitimate homes are dividers hidden from screen readers, decorative drawings, and the label of a disabled control. Anything that has to be read, every arrow that reports a state, every marker that points at the next step takes the muted text token instead. If that distinction is not written down, the token name turns into an invitation, and one day somebody gives it to real words.

None of this is done once per colour. Every new pair entering the system is checked in each theme, and the threshold it clears counts as a floor rather than a goal. Sites that ship a single theme get through this section cheaply. A store that adds a dark theme later measures every pair again on the day it does.

A control whose only cue is its border is invisible to the audit

Border tokens are split by function rather than by colour, and one question does the splitting: is the fact that this box is a control visible only from its frame?

Where the answer is yes, the border is interactive. Form fields, secondary and ghost buttons, chips and filters attached to a control, upload areas, segmented controls such as a language switcher, icon-only toggles, pagination and tab links, step indicators, and every pill whose fill matches the page background belong in that group. Where the answer is no, the border is decorative: section rules, card and panel frames, table lines, horizontal dividers, badges that cannot be clicked, ornaments hidden from assistive technology, and disabled controls.

The edge cases are what test the rule. A card whose whole surface is clickable keeps a decorative frame, because what announces the card is its heading and its text; the highlight that appears on hover does not count as an identifying cue. The underline on a text link takes no border token either — it inherits the colour of the text it belongs to, since an underline cannot look weaker than the words above it. A primary button with no border, distinguished by its fill, sits outside this section entirely; its test is the contrast between the fill and the label on top of it.

The tone of an interactive border is not picked by eye. It is the lightest step on the colour ramp that still clears the threshold, found by measurement, and no new border value is invented for a one-off case. Other guarantees travel with it: a visible focus ring on every interactive element, and full keyboard operation. The focus outline is never removed, under any circumstance. Menus, accordions, modals and step indicators can be driven from the keyboard from start to finish; when a modal opens, focus stays inside it and Esc closes it. The motion signature is a fade with a slight upward shift, and when a visitor has asked for reduced motion the transforms are switched off while opacity and instant state changes remain. On touch screens every target leaves enough room for a finger.

One rule governs what carries meaning: colour never carries it alone. An error state shows a colour and a helper message. If a gold rail marks a state, that state has a second cue as well.

These controls are not spread evenly across an online store. In a sales flow where the visitor picks hardware and paint, the selection steps and the payment form are where these controls concentrate. A store owner who wants to mark the area that needs reworking can open the buying path first and put the border question to every box on it.

When the audit says clean, ask what it did not scan

Colour contrast on our own site is measured by an automated audit. Most of what it has taught us is about what it missed rather than what it caught.

An automated audit runs on a signature. A list decides which selectors count as interactive, and a control that never matches the list does not exist as far as the audit is concerned. Here is how that played out for us. The “see all” links in the mega menu and in the navigation drawer were secondary buttons in the design system, but their class names carried none of the markers the signature looked for. The audit never saw them. While the report read clean, a low-contrast border made it into the code. A separate accessibility review caught it; the audit did not. The blind spot had a shape: a transparent background, a label in the same colour as body text, and a name built like a list link rather than like a button. We widened the signature afterwards.

After that we put the audit itself under an obligation: report how much you scanned. If the token it looks for appears in no file at all, it does not say clean — it raises an error stating that it never ran. If it cannot find the token definition file, it reports that contrast was never calculated. If a stale exemption is left behind matching nothing, that becomes a warning too. Zero findings and zero scanning no longer look the same on the screen, and that alone changed how much weight a green result carries here.

The second lesson is quieter. The right token can carry the wrong value. Somebody tunes the surface ramp, or lightens the border shade by one step. Every usage still points at the correct role name, the ratio has dropped below the threshold, and no audit that works from names will make a sound. This is why we do not read ratios off intent. They are recalculated from the raw values in the token file, in each theme, for every pairing of an interactive border role with a background or surface role.

There was a blind spot in the file filter as well. For a period the audit looked only at style and template files, and the folder holding client-side components was outside its scope. No violation happened to be sitting there at the time. But what guaranteed that was the coincidence, not the filter, and a coincidence is not an audit result.

Exemptions exist too, and they are conditional. A badge that cannot be clicked is exempt because it catches the chip signature by mistake; a disabled search field is allowed to stay decorative, and the exemption falls away on the day that field becomes usable. Every exemption is written down beside its reason.

One area stays outside this audit and we count it separately. It measures nothing that is not visible in a style file: keyboard order, the focus trap in a modal, and the name a screen reader gives a button are all outside static checking.

Why accessibility added later costs more

A contrast fix can of course be made on a live site. The question worth asking is how many places the same fix has to be made. The table below compares the same job on a site with a token layer and on a site without one.

QuestionSite with a token layerSite with colours typed into components
Where does a colour fix happenIn the token definition file, on the single line beside the role; no component file is openedIn every component file the shade appears in; the same shade sits mixed across text, border and decoration, and the file does not say which occurrence is which role
What does adding a second theme takeA new block of values under the same role names; component files do not changeA theme condition and a second value in every component; whatever is missed stays stuck in one theme
Where does the audit lookAt one token file; for each theme, every border role is calculated against every surface role from raw valuesAt pairs scattered through components; the list of pairs to measure cannot be completed, and a clean result only speaks for what was scanned
What goes into the disproportionate-burden assessmentThe roles remeasured and the result per theme; the token file draws the boundary of the workThe component files to rework and a measurement per theme in each; what enlarges the burden is not compliance but the scattering of the fix

The right-hand column looks like bad news, and it is. It is also a concrete inventory. The files to rework can be counted. The number of measurements per theme is known. What makes the burden large is that the correction has been spread across the site by an earlier decision nobody recorded as a decision.

Where a colour is going to live rarely appears on the list of decisions bound before any code is written. The table shows why it belongs there. The choice is made as though it were a matter of appearance, and the bill arrives years later under a heading nobody connected to it.

Disproportionate burden is an assessment you write, not a status you hold

There is a sentence that comes up often at this point: we will call it a disproportionate burden and move on. What that sentence actually is gets misunderstood.

The European Accessibility Act draws the boundary of the obligation like this: compliance applies where it does not fundamentally alter the basic nature of the service and does not impose a disproportionate burden. The boundary is a measurement rather than a gate. And the text is clear about who does the measuring: the operator providing the service. No authority performs the assessment and serves it on you. You perform it.

What follows the assessment is set out as well. The operator informs the relevant authority that it is relying on it, and supplies a copy only on request. So what exists is a document sitting in a file, ready to be put on a table when it is asked for. It is not an attribute you possess. It is a text that gets written, kept, and produced when required.

The technical half of this article is what fills that document. “It is disproportionate for us” is not a justification on its own; the justification is the inventory that shows the size of the work. The files to rework. The roles to be measured again in each theme. How many times the same correction has to be repeated. For a site in the right-hand column of the table that inventory is long, and its length is a fact that can be written down. For a site in the left-hand column the same inventory is short, and that is equally writable.

What the assessment will conclude in your case is not something this article can tell you; that is a question for the lawyer who applies the text of the source to your facts. What we can describe is the shape the cost side takes in code — and where your colours are written has already decided how many lines that part of the document will run to.

Scope is drawn by where your customer is, not by your address

That leaves the question of scope, and it usually arrives in one form: we publish from Türkiye, so why should this text concern us?

The definition of a service provider does not look at an address. It covers a person who provides a service on the Union market, and it also covers a person who makes offers to provide such a service to consumers in the Union. The test is not where the business is registered; it is who the service is provided or offered to. Wherever a store’s window is open, that is where the question starts.

Which services are covered is set out as a list, and e-commerce services are named on it explicitly. The definition of e-commerce is not narrow either: services provided at a distance, through websites and mobile-device-based services, by electronic means, at the individual request of a consumer, with a view to concluding a consumer contract. That description is a description of an online store’s ordinary working day.

There is a transitional arrangement as well. Service contracts concluded before a certain date may continue unchanged for a limited period until they expire. We are not putting the dates or the durations here, because those are the kind of thing that should be read in the source’s own sentences. The full text is openly available: the official text of the European Accessibility Act.

Where your site stands against that definition is a legal reading, and your lawyer will do the reading. What we can say is the part that does not change whatever the reading concludes: the cost of compliance is not held in your brand colour but in the place that colour is written on your site.

If you are building a store that sells to customers in the Union, or reworking one you already run, our e-commerce service page shows how the sellable unit is decided before the catalogue is built. That is the same round in which a colour gets its one home.

Key takeaways

  • Look at which files open when your site changes a colour; if the raw value sits in component files, there is no token layer.
  • Keep the brand gold and move its role: off text on backgrounds where it fails, onto a separate ink token where text is unavoidable.
  • An audit's clean verdict covers only the selectors in its signature, so make the audit report how much it scanned.
  • The disproportionate-burden assessment is written by the operator and supplied on request; its content is the files to rework and a measurement per theme.
  • The European Accessibility Act names e-commerce among the services it covers, and its scope test is who the service is offered to.

Questions this article answers

  • If our automated accessibility checker says the site is clean, are we done?

    You are not. An automated audit decides what counts as interactive from a list of selectors, and a control that never matches that list is never measured. Algoriel's own audit skipped links styled as buttons because their class names carried no button marker, and a low-contrast border entered the code while the report read clean; a later review caught it. Ask your tool how much it scanned, and treat keyboard order, focus traps and screen-reader names as separate checks.

  • Our brand colour fails contrast as text. Do we have to drop it?

    You do not. A shade that fails as text on a light background keeps its place in roles that are not text: a divider, an icon stroke, the single accent button in a view. Where the brand colour must carry words, a separate ink token is defined for that role, and in the dark theme that ink can share the accent's shade. The decision lives in the token file, so your components only pick a role name.

  • Can accessibility be added to a live site later, and why does it cost more?

    It can, and the cost comes from where the fixes have to happen. When raw colour values sit inside component files, a shade serves as text here, border there and decoration elsewhere, and nothing in the file says which role is which; a contrast fix is repeated in every file that carries the shade. With a token layer the same fix is a single line beside the role. Count the files your site would have to open.

  • Can we just claim disproportionate burden, and who decides that?

    The service provider assesses that itself, in writing. Under the European Accessibility Act the obligation applies to the extent that compliance neither fundamentally alters the basic nature of the service nor imposes a disproportionate burden; the operator writes the assessment, tells the authority it is relying on it, and hands over a copy only on request. Whether it holds for you is your lawyer's question; what fills it is the files to rework and a measurement per theme.

  • We publish from Türkiye but our customers are in the EU. Does the Act apply to us?

    Whether it does is for your lawyer to read from the text. The European Accessibility Act defines a service provider as anyone who provides a service on the Union market or makes offers to provide such a service to consumers in the Union; the test is who the service is offered to. E-commerce services are named explicitly among the covered services. What compliance would cost your store is decided by where its colours are written.

About the author

Algoriel

Remote web software agency

We build custom web and mobile software for businesses. Here we answer the questions that come up while your software is being built and after it goes live.

Tags:
  • web accessibility
  • European Accessibility Act
  • design tokens
  • contrast audit
  • disproportionate burden

Have a system to build?

If there is a system you want built, the quote form is the place to describe it.