From 9fdc6b60328fbf328bad6903432a6465a4d179d8 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 18 Aug 2026 02:31:13 -0500 Subject: [PATCH] fix(a11y): visible focus indicator, aria-expanded, and six Label-in-Name failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Batch 10, and only three of its six issues were real. The other three are answered on the tracker with the arithmetic. #189 — focus indicator. Footer and Home carried zero focus styling across 17 links. Added one global :focus-visible rule rather than sprinkling classes, because the issue's own scope was "all interactive and elements". Not the ring the issue asked for. It suggested ring-primary-cyan; #22D3EE is 6.26:1 on navy and 2.38:1 on white, so on this light-first design that ring would have failed WCAG 1.4.11 across most of the site. Two rings instead — white inside, navy outside — so the white carries the dark bands and the navy carries the light sections. Worst case across every background in the palette is 13.62:1. box-shadow so both rings follow each element's own border-radius, plus a transparent outline for forced-colors mode. #192 — aria-expanded={isOpen} and aria-controls on the mobile nav trigger, and the id on SheetContent it now points at. Confirmed as "false" in the prerendered HTML. #193 — INVERTED. The issue asked for aria-labels to be added consistently to hero CTAs. The aria-labels already there were WCAG 2.5.3 Label in Name failures, Level A: "Schedule a consultation" is not a superset of the visible "Schedule Consultation", so a voice-control user saying what they see cannot activate the link. Doing what the issue asked would have spread a Level A failure. Removed the six that broke it; kept the eight that genuinely add context and do contain their visible text, including the icon-only header logo link that needs one. Audit now reports 0 failures across Home, Services, Footer and Header. Verified: npm run build; the ring is in the built CSS, aria-expanded="false" and id="mobile-nav-content" are in the prerendered HTML, all six removed labels are absent from it, and the visible CTA text still renders. NOT verified: nothing has been walked keyboard-only in a browser, and no screen reader has been used. That gap is recorded in docs/qa/ClaudeQACoverage.md. Co-Authored-By: Claude Opus 5 (1M context) --- src/components/layout/Footer.jsx | 2 +- src/components/layout/Header.jsx | 2 +- src/components/layout/MobileNav.jsx | 9 +++++++-- src/index.css | 28 ++++++++++++++++++++++++++++ src/pages/Home.jsx | 8 ++++---- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/components/layout/Footer.jsx b/src/components/layout/Footer.jsx index 4f95876..9da2861 100644 --- a/src/components/layout/Footer.jsx +++ b/src/components/layout/Footer.jsx @@ -67,7 +67,7 @@ const Footer = () => { Get a Free Quote diff --git a/src/components/layout/Header.jsx b/src/components/layout/Header.jsx index 1800fbc..9b025af 100644 --- a/src/components/layout/Header.jsx +++ b/src/components/layout/Header.jsx @@ -142,7 +142,7 @@ const Header = () => { {/* CTA Button */}
- + Request Consultation
diff --git a/src/components/layout/MobileNav.jsx b/src/components/layout/MobileNav.jsx index 88fd7c8..ea2143d 100644 --- a/src/components/layout/MobileNav.jsx +++ b/src/components/layout/MobileNav.jsx @@ -40,7 +40,12 @@ const MobileNav = () => {
- - +
{ Business phone, contact center, network, and IT support built around one accountable implementation partner.

- + Schedule Consultation
@@ -241,7 +241,7 @@ const Home = () => { Four concrete differentiators that set us apart

- + Request Consultation
@@ -372,7 +372,7 @@ const Home = () => {

Share a few details and we'll provide clear direction.

- + Request Consultation