Skip to content

fix(a11y): improve keyboard and mobile task access - #979

Open
trac3r00 wants to merge 4 commits into
release/product-value-20260912-09from
release/product-value-20260912-10
Open

trac3r00 wants to merge 4 commits into
release/product-value-20260912-09from
release/product-value-20260912-10

Conversation

@trac3r00

@trac3r00 trac3r00 commented Sep 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

fix(a11y): improve keyboard and mobile task access. This is logical change 10/11 in the dependency-ordered product-audit release stack.

Refs #969

What changed

  • fix(a11y): improve keyboard and mobile task access
  • Exact source commit: 1876c4409d9b47214aa7134faf2376990e865121; validated tree: 127174c40d5e3c832097d701a032d295a9275061.
  • Depends on the preceding release-stack PR. Retarget to main only after its dependency is merged and deployed.

Why

Make output scrolling, wheel semantics, landmarks, mobile search, and shortcut help accessible.

Verification

  • bun run build passed on this exact candidate tree.
  • npm test -- --maxWorkers=2 passed on this exact candidate tree.
  • Affected behavior manually exercised as described below.
  • Latest GitHub Build, Unit Tests (Vitest), and E2E Tests (Playwright) must all pass before merge.
Tests  781 passed (781)
CANDIDATE_BUILD_UNIT_GREEN
Committed tree equals validated tree: 127174c40d5e3c832097d701a032d295a9275061

Six focused browser cases passed. WebKit controls meet target sizes; nine fresh desktop/mobile/CJK screenshots passed two independent visual reviews.

Final combined tree additionally passed 801 unit tests and all 293 Playwright tests with retries disabled, plus all 48 primary tool workflows at desktop and mobile. The exploratory Color Converter exact-HEX boundary remains a documented pre-existing defect; its runtime is unchanged by this stack.

Risk & rollback

  • Risk: Dependent commits require earlier stack changes; merge in order.
  • Rollback: revert this PR through a new PR; do not revert dependencies beneath already-merged dependents.
  • Release: require an approving review and latest-SHA CI. Respect the 15-minute soak between deploy-affecting merges and verify the production deployment before continuing.

Summary by cubic

Fixes keyboard and mobile task access so output regions are reachable, shortcut help is a real dialog, and the mobile home page keeps the first matching card visible.

Changes

  • Adds focusable, named scroll regions to the regex visualizer and CSS gradient generator; the gradient output's accessible name is localized.
  • Removes nested interactive and duplicate landmark semantics in the roulette wheel, FAQ accordions, and blog code samples.
  • Makes shortcut help a real dialog: receives focus on open, traps Tab, closes on Escape, and returns focus to the trigger.
  • Suppresses only the page's own mod shortcuts (like mod+K nav search) while the dialog is open; other mod combinations keep native behavior and IME-composing keydowns never trigger page shortcuts.
  • Moves the shortcut help trigger into document flow on mobile, turns the flagship links into a horizontal reel, and lets DNS record-card categories wrap on narrow cards.
  • Fixes low-contrast secondary text and plain target-size heights for native selects, plus Playwright coverage for the new behavior.

Rollout

  • Depends on the preceding release-stack PR; merge and deploy this stack in order.

Written for commit cd72e5b. Summary will update on new commits.

Review in cubic

Keep output regions keyboard reachable, remove nested/duplicate semantics, preserve modal focus and make mobile search and shortcut help unobstructed.

Ultraworked with [omo](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 17 files

Confidence score: 4/5

  • In src/ui/blog.js, labelCodeSampleRegions matches no article code blocks because their accessible labels are descriptive rather than Code sample, so the intended labeling is not applied; update the matching logic to recognize the labels actually used.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/ui/blog.js">

<violation number="1" location="src/ui/blog.js:356">
P2: labelCodeSampleRegions never matches: no article content (English or any locale) contains `aria-label="Code sample"` — the code blocks use descriptive labels like `aria-label="Invalid and valid JSON examples"` and `aria-label="curl JSON request example"`. The replacement is therefore a no-op and the intended numbered region labels are never applied to screen-reader users. Update the content labels or the regex so it targets the actual `aria-label` values in BLOG_ARTICLES and the localized content.</violation>
</file>

Shadow auto-approve: would not auto-approve because issues were found.

Re-trigger cubic

Comment thread src/utils/keyboard-shortcuts.js Outdated
Comment thread src/ui/blog.js Outdated
function labelCodeSampleRegions(content) {
let sampleNumber = 0;
return String(content || "").replace(
/aria-label="Code sample"/g,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: labelCodeSampleRegions never matches: no article content (English or any locale) contains aria-label="Code sample" — the code blocks use descriptive labels like aria-label="Invalid and valid JSON examples" and aria-label="curl JSON request example". The replacement is therefore a no-op and the intended numbered region labels are never applied to screen-reader users. Update the content labels or the regex so it targets the actual aria-label values in BLOG_ARTICLES and the localized content.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/ui/blog.js, line 356:

<comment>labelCodeSampleRegions never matches: no article content (English or any locale) contains `aria-label="Code sample"` — the code blocks use descriptive labels like `aria-label="Invalid and valid JSON examples"` and `aria-label="curl JSON request example"`. The replacement is therefore a no-op and the intended numbered region labels are never applied to screen-reader users. Update the content labels or the regex so it targets the actual `aria-label` values in BLOG_ARTICLES and the localized content.</comment>

<file context>
@@ -350,6 +350,14 @@ export function renderBlogListingPage(lang = DEFAULT_LANGUAGE) {
+function labelCodeSampleRegions(content) {
+  let sampleNumber = 0;
+  return String(content || "").replace(
+    /aria-label="Code sample"/g,
+    () => `aria-label="Code sample ${++sampleNumber}"`,
+  );
</file context>

Comment thread styles/input.css Outdated
Comment thread src/routes/css-gradient-generator.js Outdated
Comment thread src/routes/dns-reference.js
- Keep global shortcuts (mod+K nav search) from pulling focus out of the open
  shortcut help dialog; Escape closes it from any focus position.
- Drop the no-op blog code-sample relabeling; descriptive labels stay.
- Scope the WebKit select height to .input/.input-mono via :where() so compact
  and custom selects keep their own size (cidr prefix, roulette).
- Localize the gradient CSS output accessible name via data-i18n-aria.
- Let DNS record-card categories wrap on narrow mobile cards.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 19 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would not auto-approve. Auto-approval blocked by 1 unresolved issue from previous reviews.

Re-trigger cubic

Only suppress the page's own mod shortcuts while the help dialog is open, so
other mod combinations keep native behavior; ignore IME-composing keydowns;
and clean up the guard even if the dialog node was removed externally.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread src/utils/keyboard-shortcuts.js Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 2 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would not auto-approve. Auto-approval blocked by 1 unresolved issue from previous reviews.

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant