Accessibility

Accessibility is usually the part of my work nobody asked for and everybody eventually needs. I've spent years making the case for WCAG compliance before a client or company was ready to hear it — sometimes they weren't, and found out the expensive way. I reauthored my team's internal ARIA and WCAG 2.2 AA development guide because arguing from a documented standard works better than arguing from opinion.

That guide is internal, so you cannot read it. This page is the next best thing: the same practice applied to a site you can inspect right now. Every claim below is checkable in devtools.

How I approach it

A standard beats a remediation pass

The expensive version of accessibility is the one where a team builds an interface, an audit finds two hundred issues, and someone retrofits fixes component by component. The cheap version is a documented standard the team builds against from the start.

Writing my team's ARIA and WCAG guide was worth more than any individual fix I made, because it moved the work from repeated remediation to something reusable. New builds started closer to compliant, and the audit findings got shorter.

Measure, do not eyeball

Contrast is the clearest example. A color pairing that looks fine is routinely a few tenths under the threshold, and nobody catches it by looking. While building this site I picked a muted gray for small text that measured 4.36:1 against the footer background — under the 4.5:1 bar, and invisible to the eye. It was measured, and so it was caught and changed.

Semantics before ARIA

The best ARIA is usually the ARIA you did not need to write. A real <button>, a real <nav>, and a correct heading order solve most of what people reach for role attributes to patch. ARIA is for the cases the platform genuinely does not cover, and it has to be kept valid — an attribute pointing at an element that is not in the DOM is worse than no attribute at all.

Respect preferences the user already expressed

People who need reduced motion, a dark color scheme, or larger text have usually said so at the operating system level already. Honoring prefers-reduced-motion and prefers-color-scheme costs almost nothing, and overriding them rarely has a good justification.

This site, specifically

Things you can verify without taking my word for any of it.

  • Focus states were written first

    A single global :focus-visible rule was the first thing in the stylesheet, before any color or type decisions, so every interactive element added afterwards inherited a visible ring by default. Tab through this page and watch it follow you.

  • A skip link that actually goes somewhere

    Press Tab from the top of any page. The first stop is a skip link to the main landmark, which is focusable and moves the caret rather than only scrolling.

  • One h1 per page, in a sensible order

    Each page has exactly one h1 and no skipped heading levels, so the document outline is navigable by heading in a screen reader.

  • The mobile menu keeps its ARIA valid

    The disclosure button has aria-expanded and aria-controls. The panel it references stays in the DOM permanently and is toggled with the hidden attribute, because rendering it conditionally would leave aria-controls pointing at an id that does not exist. Escape closes it and returns focus to the button.

  • Motion is opt-in

    Smooth scrolling and transitions are gated behind prefers-reduced-motion. Turn on reduce-motion in your OS and reload; the behavior changes.

  • The contact link degrades

    The email address is assembled in the browser so it never appears in the served HTML, but the call to action is a real anchor server-side rather than a span dressed as a button — it is focusable and it works with JavaScript disabled.

Measured contrast

Every text and background pairing in the palette, computed with the WCAG relative luminance formula in both color schemes. AA requires 4.5:1 for body text; the lowest value here is 4.97:1.

Contrast ratios for each foreground and background pairing, in light and dark color schemes.
PairingLightDark
Body text on page background17.41:115.66:1
Muted text on page background7.39:18.35:1
Small text on page background5.29:16.01:1
Link accent on page background5.91:19.95:1
Small text on card and footer surfaces4.97:15.20:1
Accent on accent-tinted surface5.52:18.35:1
Button label on accent fill6.06:19.95:1

Where this tends to be useful

Usually one of three situations: an audit came back long and someone has to work through it without breaking the design; a team wants a standard so the next build does not repeat the same findings; or a public-sector or education client has a compliance obligation and the codebase was not written with one in mind. I have worked all three.