royeyal.com
Accessibility
I build accessible sites for a living, so this one had better be one. Here is what that actually amounts to, how it was checked, and what is still missing.
Last updated
Where it stands
This site is built to meet WCAG 2.2 Level AA. That is a target I have tested against myself, not a formal conformance claim: nobody independent has audited this site, and it carries no certification. Treat the list below as evidence you can go and check, and the list after it as the reason I am not claiming more.
This statement covers the homepage at royeyal.com, the one-page CV at /cv, these two document pages, and the 404 page — which is the whole site.
How it is built
Structure
-
One
<h1>per page and headings that descend in order, with no skipped levels — so a screen reader's heading list is a usable table of contents rather than a flat wall. -
Real landmarks (
header,main,nav,footer), and the navigation elements carry labels so they can be told apart. -
A language is declared on every page, and every image has an
altattribute. Purely decorative graphics — the animated hero backdrop, the scanline overlay, the company logos that sit beside a heading already carrying the name — are hidden from assistive technology instead of being announced twice. - Every page still reads with JavaScript switched off. The reveal animations start from the element's natural visible state, so a bundle that never loads costs you the motion, not the content.
Keyboard
-
Everything interactive is reachable and operable from the keyboard, in
document order. There is no positive
tabindexanywhere, so the tab order is the reading order. - Focus is always visible: a 2px cyan outline, offset from the element, applied site-wide rather than per component — and never removed without a replacement.
-
The floating menu is inert while it is closed, so it is not a set of
invisible tab stops you have to page through. Opening it reports
aria-expanded, and Esc closes it. - Standalone controls are sized to the 24 × 24 px floor that WCAG 2.2 introduced. Links inside a sentence are left at text size, which is the exception the same rule allows.
Motion and sound
-
prefers-reduced-motionis honored, and not just by a blanket rule that zeroes durations. The hero intro, the scroll-driven timeline and the scroll behavior each have their own reduced branch, and the animated WebGL backdrop renders a single static frame instead of running a render loop. - Nothing moves, flashes or auto-plays without you starting it. Sound effects are off until you switch them on, and the toggle reports its state rather than just looking different.
Color and layout
- Text contrast was measured, not eyeballed: every visible run of text on the homepage and the CV was checked against its actual composited background. None of it falls below AA. Muted body copy sits around 8:1, well clear of the 4.5:1 floor.
- Color is never the only signal. Links in prose are underlined, and states that matter are carried by text or an ARIA property as well as a color change.
- The layout reflows to a 320 px viewport with no horizontal scrolling, and sizes are in relative units so browser zoom and a larger default font size both work.
- Confirmation messages are announced. Copying my email address updates a polite live region, and the visual "Copied" flash is hidden from screen readers so the same fact is not said twice.
How it was tested
Self-assessment, most recently on , covering:
- A programmatic pass over the rendered DOM — heading order, landmarks, alt text, accessible names on every focusable control, tab order, and the state of the menu while closed.
- Contrast measured on every visible text node against its composited background, rather than sampling a few tokens by hand.
- Reflow and layout checked down to a 320 px viewport.
- The no-JavaScript and print paths, both of which are easy to break with scroll-triggered reveals and both of which work.
What is still missing
The most useful thing on this page is this list, not the one above it. Automated checks catch a minority of real accessibility problems. These are the gaps I know about.
- No end-to-end screen reader pass. The markup and ARIA have been reviewed carefully, but I have not yet sat down and driven the whole site with VoiceOver, NVDA and JAWS in turn. Until I have, anything on this page about how it sounds is inference from the code, not observation.
- No independent audit. Everything here is my own assessment of my own work, which is the weakest kind of assessment there is.
- Contrast over the hero backdrop is not a fixed number. The headline sits over an animated WebGL layer, so the ratio moves as it moves. The body color used there is chosen to hold roughly 8:1 against the lit backdrop, but that is a measurement taken at one moment rather than a guarantee, and no automated tool can check it.
-
Sound has no system preference to obey. There is a
prefers-reduced-motion; there is no equivalent for audio. Off-by-default and an explicit toggle is the best answer I have, and it is a choice rather than a solved problem. - Links leave this site. LinkedIn, GitHub and the client sites in the work section are not mine, and I cannot speak for how accessible they are.
Telling me something is broken
If any part of this site is hard or impossible to use, I want to know — including, and especially, something that is not on the list above.
Email hello@royeyal.com. What helps: the page, what you were trying to do, and what your setup is — browser, operating system, and any assistive technology, with versions if you have them. Any one of those is better than not writing.
I will reply within five working days. If it is something I can fix, I will tell you when it is fixed; if it is not, I will tell you that plainly instead of leaving it open.
This is a personal site, so there is no formal enforcement procedure behind that promise — only me, and this page, which is a public record of what I said I would do.