diff --git a/internal/check/check_a11y_test.go b/internal/check/check_a11y_test.go
new file mode 100644
index 0000000..f8aca28
--- /dev/null
+++ b/internal/check/check_a11y_test.go
@@ -0,0 +1,441 @@
+package check
+
+import (
+ "context"
+ "strings"
+ "testing"
+
+ "github.com/GrayCodeAI/inspect/internal/crawler"
+)
+
+// This file was split out of check_test.go for readability (mechanical move; no behavior change).
+
+// --- Advanced A11y Tests ---
+
+func TestCheckARIA_InvalidRole(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `
Content
`)
+
+ findings := checkARIA(page)
+
+ found := false
+ for _, f := range findings {
+ if strings.Contains(f.Message, "Invalid ARIA role") && strings.Contains(f.Message, "banana") {
+ found = true
+ if f.Severity != SeverityMedium {
+ t.Errorf("expected medium severity for invalid role, got %v", f.Severity)
+ }
+ }
+ }
+ if !found {
+ t.Error("expected finding for invalid ARIA role 'banana'")
+ }
+}
+
+func TestCheckARIA_ValidRole(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `Nav content
`)
+
+ findings := checkARIA(page)
+
+ for _, f := range findings {
+ if strings.Contains(f.Message, "Invalid ARIA role") {
+ t.Errorf("should not flag valid ARIA role: %s", f.Message)
+ }
+ }
+}
+
+func TestCheckARIA_PositiveTabindex(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `Content
`)
+
+ findings := checkARIA(page)
+
+ found := false
+ for _, f := range findings {
+ if strings.Contains(f.Message, "Positive tabindex") {
+ found = true
+ if f.Severity != SeverityMedium {
+ t.Errorf("expected medium severity, got %v", f.Severity)
+ }
+ }
+ }
+ if !found {
+ t.Error("expected finding for positive tabindex")
+ }
+}
+
+func TestCheckARIA_ZeroTabindex(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `Content
`)
+
+ findings := checkARIA(page)
+
+ for _, f := range findings {
+ if strings.Contains(f.Message, "Positive tabindex") {
+ t.Error("tabindex=0 should not be flagged")
+ }
+ }
+}
+
+func TestCheckARIA_NegativeTabindex(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `Content
`)
+
+ findings := checkARIA(page)
+
+ for _, f := range findings {
+ if strings.Contains(f.Message, "Positive tabindex") {
+ t.Error("tabindex=-1 should not be flagged as positive tabindex")
+ }
+ }
+}
+
+func TestCheckARIA_AriaHiddenOnFocusable(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `Hidden link`)
+
+ findings := checkARIA(page)
+
+ found := false
+ for _, f := range findings {
+ if strings.Contains(f.Message, "Focusable element is aria-hidden") {
+ found = true
+ if f.Severity != SeverityHigh {
+ t.Errorf("expected high severity, got %v", f.Severity)
+ }
+ }
+ }
+ if !found {
+ t.Error("expected finding for aria-hidden on focusable element")
+ }
+}
+
+func TestCheckARIA_AriaHiddenOnNonFocusable(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `Decorative icon
`)
+
+ findings := checkARIA(page)
+
+ for _, f := range findings {
+ if strings.Contains(f.Message, "Focusable element is aria-hidden") {
+ t.Error("should not flag aria-hidden on non-focusable element")
+ }
+ }
+}
+
+func TestCheckARIA_InteractiveElementRemovedFromTabOrder(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ ``)
+
+ findings := checkARIA(page)
+
+ found := false
+ for _, f := range findings {
+ if strings.Contains(f.Message, "Interactive element removed from tab order") {
+ found = true
+ }
+ }
+ if !found {
+ t.Error("expected finding for interactive element with tabindex=-1")
+ }
+}
+
+func TestCheckARIA_RoleRequiringNameWithoutName(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ ``)
+
+ findings := checkARIA(page)
+
+ found := false
+ for _, f := range findings {
+ if strings.Contains(f.Message, "has no accessible name") {
+ found = true
+ if f.Severity != SeverityHigh {
+ t.Errorf("expected high severity, got %v", f.Severity)
+ }
+ }
+ }
+ if !found {
+ t.Error("expected finding for role=button without accessible name")
+ }
+}
+
+func TestCheckARIA_RoleRequiringNameWithAriaLabel(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ ``)
+
+ findings := checkARIA(page)
+
+ for _, f := range findings {
+ if strings.Contains(f.Message, "has no accessible name") {
+ t.Error("should not flag element with aria-label")
+ }
+ }
+}
+
+func TestCheckARIA_EmptyBody(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"}, "")
+ findings := checkARIA(page)
+ if len(findings) != 0 {
+ t.Error("should not produce findings for empty body")
+ }
+}
+
+func TestCheckLandmarks_AllPresent(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `
+
+
+ Content
+
+
+ `)
+
+ findings := checkLandmarks(page)
+
+ for _, f := range findings {
+ if strings.Contains(f.Message, "missing") {
+ t.Errorf("should not flag missing landmark when all present: %s", f.Message)
+ }
+ }
+}
+
+func TestCheckLandmarks_MissingNav(t *testing.T) {
+ page := makePage("https://example.com", 200, map[string]string{"Content-Type": "text/html"},
+ `Content`)
+
+ findings := checkLandmarks(page)
+
+ found := false
+ for _, f := range findings {
+ if strings.Contains(f.Message, "missing