// ACCESSIBILITY
This site targets WCAG 2.2 Level AA conformance, plus AAA contrast for body text. The full design lives in the accessibility design doc.
What's tested in CI
- axe-core via Playwright on every PR
- Lighthouse accessibility category, every audited route
- Token contrast unit tests (AAA body, AA decorative)
- Heading-increment + img-alt MDX lints
- Post-build HTML structural assertion (single h1, single main, named navs, no positive tabindex, accessible names on buttons/links)
- Keyboard-traversal smoke (no traps, focus visible)
Third-party scope
The following surfaces are tested at the container level only; their internals are upstream:
- webmention.io — the response shape is upstream; the rendered list is gated.
- Pagefind UI — default styles on
/search; we scope-override where needed.
Known limits
- `--accent` / `.eof` aria-hidden decorative elements flagged for contrast (light theme) (Minor, WCAG 1.4.3 Contrast (Minimum) — likely exempt (decorative), but axe flags it) — Axe flags the `.eof` `<span class="eof" aria-hidden="true">$ exit </span>` element on every route (home, archive, post, about, search, 404 — light theme) and the `<pre class="signage" aria-hidden="true">` block on the 404 page. All affected elements carry `aria-hidden="true"`, making them invisible to AT. WCAG 1.4.3 exempts "purely decorative" text; these elements convey no information (terminal prompt aesthetics only). Axe cannot automatically determine decoration intent and flags all visible text. The 404 `<pre>` block's embedded `#not-found-path` span is handled separately in F-001. This finding covers the aria-hidden decorative fragments only.
- Home page has no `<h1>` (both themes) (Major, WCAG 1.3.1 Info and Relationships (also axe `best-practice` tag, but the structural gap is real)) — The home page renders no `<h1>` element. The site header brand link `$kevinkiklee.io` is inside an `<a>` (not a heading), and the section titles "latest" and "featured projects" are rendered as `<h2>` via `SectionTitle`. AT users navigating by headings land in a document with no h1, which is disorienting. The axe `page-has-heading-one` rule flags this on both light and dark theme audits. Confirmed by static review as a real structural gap (not a false positive).
Reporting an issue
Either DM me on Mastodon or open a GitHub issue.