- Prefer native controls or correct ARIA roles (e.g.
role="switch"+aria-checkedfor toggles,role="progressbar"witharia-valuenow/ min / max for progress). - Icon-only buttons need an accessible name (
aria-label), not onlytitle. - Slide-over panels that trap focus use
useSlideOversemantics:role="dialog",aria-modal="true", Escape to close, Tab wrap, restore focus on close. - Associate form fields with
<label htmlFor>andaria-describedbyfor help text. - Keep
document.documentElement.langin sync with the active locale (seefrontend/src/i18n.ts). - Respect
prefers-reduced-motionwhere animations are decorative (seefrontend/src/index.cssanduseReducedMotionin Framer Motion where used). - Modal
role="dialog"nodes should have a computed accessible name (aria-labelwith the same string as the visible title is used on slide-overs). - Long scrollable areas use
ScrollableRegion(tabIndex={0},role="region",aria-label) so keyboard users can focus the container and scroll.
- Theme provides landmarks, search, and keyboard navigation; avoid overrides that remove focus outlines or drop contrast below WCAG AA without a strong reason.
- Figures should include meaningful
alttext (or emptyaltonly when the image is purely decorative and the caption carries the meaning). Repository check: no barewithout description. - Card tiles (
.card-linkwrapping an entire feature card on the localized home pages): add an explicitaria-labelin the opening<a>that states the destination (e.g. “User guide: … section”) so assistive tech does not rely on emoji/icons or horizontal rules for the link name. Keep labels in sync acrossdocs/index.md,docs/es/index.md,docs/de/index.md, anddocs/fr/index.md. - After substantive theme or CSS changes, run an automated pass on the built site (e.g. Lighthouse accessibility category or
@axe-core/cliagainstsite/aftermkdocs build) and fix regressions. docs/stylesheets/extra.cssbumps muted foreground contrast on the slate scheme and underlines in-content links so they are not identified by color alone.docs/javascripts/scrollable-focus.jsalso: setsaria-labelon.md-search[role="dialog"](Material search overlay); givesnav.md-code__nava uniquearia-labelper code block (copy toolbar); uses sequential, uniquearia-labelstrings for each scrollable code/tablerole="region"(with optional figure caption / table caption); subscribes to Material’sdocument$stream so these fixes re-apply after instant navigation.
- Frontend:
frontend/src/components/SettingsPanel.tsx,App.tsx(header +BatchProgress),ScrollableRegion.tsx,DropZone.tsx,ConversionProgress.tsx,ExportOptions.tsx, panel components,frontend/src/hooks/useSlideOver.tsx,frontend/src/i18n.ts,frontend/src/index.css,frontend/tailwind.config.js. - Docs:
docs/overrides/main.html,docs/stylesheets/extra.css,docs/javascripts/scrollable-focus.js.