NavbarWrapper promoted from role="banner" to role="navigation" with aria-label="Main navigation". Resolves landmark-banner-is-top-level across every page site-wide.
role="contentinfo" and aria-label="Site footer" added to .footer_component div. Resolves region landmark violations across every page site-wide.
Newsletter signup <section> was unnamed. Added aria-label="Newsletter signup" to create a valid named landmark, resolving region violations on all pages using this component.
Deployed ADA Weglot Role Fix site-wide: removes role="none" from Weglot <aside> on page load and via MutationObserver. Addresses presentation-role-conflict globally.
<aside role="none"> carries aria-label — conflicting signals for screen readers.
Site script removes role="none" from Weglot aside on load and via MutationObserver.
.main-navigation div labeled "Utility navigation" sits outside any landmark region.
Already carries role="navigation" in Webflow component — clears on next publish.
#ff861f orange (2.41:1 ratio, needs 4.5:1).
Runtime script overrides button background to #b05700 — same orange family, passes 4.5:1.
#weglot-language-es anchor with tabindex="-1" inside interactive control.
Runtime script removes negative tabindex from Weglot anchor.
.storerocket-filters-list scrollable but not keyboard accessible.
Runtime script adds tabindex="0" to the filters list element.
<h4> region headings (West, Central, East) appearing directly after <h1>.
All three changed to <h2> in Webflow Designer.
.layout13_content divs outside landmark regions.
Added role="region" with descriptive aria-label to both in Designer.
role="button" — invalid on <label> elements.
v2 script with attribute MutationObserver strips role and tabindex as Jetboost sets them.
<input type="checkbox"> with role="button" nested inside interactive labels.
Same script removes role="button" from inputs; native checkbox semantics restored.
<span role="checkbox"> elements missing required aria-checked attribute.
Script derives and sets aria-checked from active/selected class state, kept in sync.
#667e9f on #f6fbff (3.99:1); inline styles overriding script.
v2 script uses setProperty('color','#4a6080','important') to override inline styles.
<h6> "At San Ysidro Health, patient-centered…" inside Rich Text field — invalid level in sequence.
Page-scoped script replaces <h6> in .w-richtext with <p>. Content team advised to fix at CMS source.
<h4> after <h2>, with <h3> siblings after them.
Both changed to <h3> in Designer. Sequence: h1 → h2 → h3 → h3 → h3 → h3.
<h3> section headings directly after <h1> — skips <h2> entirely.
All three promoted to <h2> in Designer.
<h1> on page — entire heading tree starts at <h4> and <h5>.
Page title promoted h2 → h1. 30 subsequent headings restructured across the full page hierarchy.
<h4>, <h5> elements cascading from missing <h1>.
Full hierarchy restructured: h1 → h2 → h3 → h3 → h3 → h3 → h3 → h3 → h3 → h4 ×24.
<h4> section headings and fourteen <h5> topic headings — skips <h2> and <h3>.
16 headings restructured: section headers → h2, topic headings → h3. Final: h1 → h2 → h3×8 → h2 → h3×7.
#movie_player div has aria-label but no valid role attribute.
Page-scoped script adds role="application" — the correct semantic role for an embedded media player.
<h3> and <h5> skipping levels after <h1>.
2 headings → h2, 5 headings → h3 in Designer.
.table4_component had role="table" but contained forms, lists, nav, buttons — invalid table children.
Removed role="table", aria-label, and aria-describedby from wrapper in Designer. Resolves 11 aria-required-parent cascade violations.
<a role="row"> and <div role="cell"> — invalid roles on these elements.
Runtime script removes role="row" and role="cell" from all CMS list link elements.
aria-label on <div> with no role.
Script adds role="slider" plus required aria-valuemin/max/now attributes.
<select> has no accessible label.
Added aria-label="Filter health library by category" in Designer.
<h3> "Featured Resource" after <h1>; empty library item link.
Heading → h2 in Designer. Script derives aria-label from link text content.
<h4> and <h5> headings authored by content editors skipping levels after page <h1>.
URL-scoped site script: promotes .w-richtext h4 → h2 and h5 → h3 across all /health-library/* pages.
<h5> "Certified Eligibility Specialists" after <h1>; <h4> "MEDI-CAL" in wrong sequence.
6 headings restructured in Designer: h5 → h2, h3 → h2, four h4s → h3.
aria-label="More information". Footer social links confirmed already labelled — clears on publish.
<h4> section headings out of sequence.
7 headings corrected to h3 in Designer.
.email-banner) content outside landmarks on all pages.
Alert Bar Two component: added aria-label="Newsletter signup" to <section> root — resolves globally.
#movie_player div — aria-label without role.
Page-scoped scripts add role="application" on each page.
<h4> "La Casita" out of sequence (history page only).
Page-scoped script replaces Rich Text h4 → h2 on render.
<h2> — no <h1> present. Shared layout pattern.
Page title heading promoted h2 → h1 on each page in Designer.
<h3> "What is EpicCare Link?" skips <h2>; <h5> "Requesting Access" further out of order.
3 headings restructured: h3 → h2, h5 → h3, h4 → h3.
aria-label without role.
Page-scoped script adds role="application".
<h5> core value headings after <h3>; <h4> "Our Mission" misplaced.
Core values → h4; "Our Mission" → h3 in Designer.
.chip-button-provider white text on #3a88b4 (3.91:1 ratio).
Page script overrides background to #2a6a8f — passes 4.5:1 against white.
.is-link.is-icon links with role="button" containing child <div role="button">.
Removed role and tabindex from parent links in Designer; child divs cleaned via script.
aria-label="Learn more about San Ysidro Health" in Designer.
<h1> elements — "Browse Job Openings", "Medical", "Dental", "Behavioral Health", "PACE" all incorrectly tagged h1.
9 headings restructured in Designer: Browse → h2, specialty cards → h3, feature cards → h3.
<h6> "patient-centered" — same recurring CMS authoring pattern.
URL-scoped site script fires on all /services/*: replaces .w-richtext h6 → <p> and h4 → h2.
#ae-embed-calendar): nav tabs #006eff (4.49:1), time labels #999999 (2.84:1), weekend day names #349ad4 (3.12:1), event titles failing.
Page-scoped script overrides 4 color tokens to accessible equivalents. MutationObserver re-applies on month navigation.
.is-link.is-icon links with role="button" and focusable child divs.
Removed role and tabindex from both link elements in Designer.
<h5> elements directly after <h1>.
Both promoted to <h2>; "In-Home Vaccination Program" → <h3> in Designer.
All scripts are deployed via the Webflow Scripts API and hosted on Webflow's CDN. Site-level scripts run on every page; page-scoped scripts run only on the specified page.
| Script Name | Scope | What It Fixes |
|---|---|---|
| ADA Weglot Role Fix | Site-wide | Removes conflicting role="none" from Weglot <aside> so aria-label is honored. MutationObserver keeps it clean on language switch. |
| ADA Locations Runtime Fix | Site-wide | StoreRocket button contrast (#b05700), tabindex="0" on filters list, Weglot tabindex cleanup, Weglot aside suppression. |
| ADA Services Detail Fix | URL: /services/* | Replaces CMS Rich Text h6 → p and h4 → h2 on all service detail pages. |
| ADA Health Library Detail Fix | URL: /health-library/* | Promotes h4 → h2 and h5 → h3 in Rich Text blocks on all health library detail pages. |
| ADA Providers Fix v2 | Page: providers-overview | Strips Jetboost role="button"/tabindex from filter labels via attribute MutationObserver. Fixes provider specialty text contrast with !important. Syncs aria-checked state. |
| ADA Providers Overview Fix | Page: providers-overview | Legacy v1 — superseded by v2. Retained for rollback. |
| ADA Services Page Fix | Page: /services | Replaces CMS h6 → p inside .w-richtext on the Services overview page. |
| ADA Pay Bill YouTube Fix | Page: pay-my-bill-my-chart | Adds role="application" to YouTube #movie_player div to allow aria-label. |
| ADA History Page Fix | Page: /history | YouTube role="application" fix + Rich Text h4 → h2 for "La Casita" heading. |
| ADA Patient Impact Fix | Page: /patient-impact | YouTube role="application" fix. |
| ADA Health Library Fix | Page: health-library | Range slider role="slider" + required value attributes; removes invalid role="row"/role="cell"; derives aria-label for empty links. |
| ADA Join Our Team Fix | Page: join-our-team | YouTube role="application" fix. |
| ADA Become Provider Fix | Page: become-a-provider | Chip button contrast (#2a6a8f); removes role="button"/tabindex from child divs inside icon links. |
| ADA Vaccines Page Fix | Page: /vaccines | Overrides 4 Acuity Scheduling calendar color tokens to accessible equivalents; re-applies on calendar navigation via MutationObserver. |
| ADA Locations Runtime Fix | Page: /locations | Page-scoped instance for locations-specific StoreRocket and Weglot issues. |
Weglot injects an <aside> element with aria-label="Language selected: English" and a child <li> with role="option" containing a focusable anchor. This structure generates two recurring violations on every page where Weglot is active:
presentation-role-conflict — Weglot sets role="none" on the <aside> to suppress it as a landmark, but the aria-label attribute conflicts with that role. Screen readers receive contradictory signals.
nested-interactive — The <li role="option"> contains an <a> anchor. Nesting a focusable link inside a list option that is itself interactive creates focus ambiguity for assistive technologies.
role="none" and strips negative tabindex from the anchor on page load and via MutationObserver on language switch. This reduces — but does not eliminate — violations because Weglot's DOM structure is non-deterministic across domains and reinitialization events.
<aside> to <div>, and disable keyboard tabindex injection on the language anchor. This resolves both violations at source and eliminates the need for any DOM patching. Weglot's support team can assist.
The provider directory filter on /providers-overview is powered by a combination of Jetboost and Finsweet CMS Filter. Their initialization scripts set role="button" and tabindex="0" on native <label> elements wrapping filter checkboxes. This generates two violations per filter option:
aria-allowed-role — role="button" is not a permitted ARIA role on <label> elements. Labels have an implicit role tied to their associated input.
nested-interactive — The <label> with role="button" contains a hidden <input type="checkbox">. Two interactive roles in a parent-child relationship cause focus and announcement conflicts in screen readers.
attributes: true to intercept and strip role and tabindex whenever Jetboost sets them, keeping pace with the widget's initialization. This is effective but fragile — a Jetboost version update could break the timing.
role="button" from label elements in their filter widget — native <label> elements associated with checkboxes are already interactive without a role override. This is a straightforward change on their end. File a support ticket with Jetboost referencing WCAG 2.1 SC 4.1.2 (Name, Role, Value).
The clinic location finder on /locations, /services/urgent-care, and other pages renders "Visit Clinic Page" call-to-action buttons with white text on #ff861f orange — a contrast ratio of 2.41:1 against a required minimum of 4.5:1.
color-contrast — .storerocket-result-website-link fails at 2.41:1. The scrollable filter list also lacks keyboard accessibility (scrollable-region-focusable).
#b05700 (passes 4.5:1) and adds tabindex="0" to the filters list. These overrides hold unless StoreRocket's CSS changes specificity.
.storerocket-result-website-link background color to a WCAG-compliant value. The current orange (#ff861f) cannot pass contrast with white text at any reasonable size. #b05700 or darker is recommended. Also request StoreRocket add tabindex="0" to their filters container natively. File a ticket at StoreRocket support referencing WCAG 2.1 SC 1.4.3 and 2.1.1.
The vaccination event calendar on /vaccines embeds an Acuity Scheduling widget (#ae-embed-calendar-EN8468291) that renders several UI elements in colors that fail WCAG contrast requirements:
#006eff on white (4.49:1 — just misses 4.5:1); time labels #999999 (2.84:1); weekend day names #349ad4 (3.12:1). All fail for normal-weight text at their rendered sizes.
A recurring pattern across multiple pages: content editors are using heading tags inside Webflow Rich Text fields that skip levels — most commonly starting subsections at <h4> or <h5> when the page's first heading is an <h1> or <h2>. This was observed on:
<h6> "patient-centered" in Rich Text<h4> content headings throughout CMS entries<h4> "La Casita" in Rich Text field<h1>. Deeper subsections should cascade: H2 → H3 → H4, never skipping a level. Runtime scripts currently compensate for these errors, but the correct fix is at the content level. A brief style guide addition or a Webflow Rich Text heading level training session for the content team would prevent recurrence.