From 5bd97f66f7c58c2c5adc9f7427e5bc3b76c5f7f8 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 22 Oct 2026 22:28:03 +0000 Subject: [PATCH 1/2] Name controls, headings, and the toast region for assistive tech. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Card titles default to h2 so a page h1 is not followed by an h3. Generate and flowchart selects, the timer progress bar, and attack options have accessible names, the toast region follows the UI language, and the landing demo leaves the tab order. Co-authored-by: Gáborjáni-Szabó Ádám --- e2e/navigation-performance.spec.ts | 2 +- src/components/LanguageSwitcher.tsx | 4 +- src/components/features/attack/AttackForm.tsx | 16 ++- .../features/attack/AttackResults.tsx | 10 +- .../features/brainstorm/BrainstormResults.tsx | 6 +- .../features/factoids/FactoidsResults.tsx | 6 +- .../features/generate/GenerateForm.tsx | 26 +++- .../features/generate/GenerateResults.tsx | 24 ++-- src/components/landing/Hero.tsx | 5 +- src/components/ui/card.tsx | 13 +- src/components/ui/empty-state.tsx | 2 +- src/components/ui/progress.tsx | 1 + src/components/ui/sonner.tsx | 1 + src/locales/en.json | 3 + src/locales/es.json | 3 + src/locales/hu.json | 3 + src/pages/AdminPage.tsx | 4 +- src/pages/FlowchartPage.tsx | 21 +-- src/pages/TimerPage.tsx | 2 +- src/test/a11y/names-and-headings.test.tsx | 128 ++++++++++++++++++ 20 files changed, 222 insertions(+), 58 deletions(-) create mode 100644 src/test/a11y/names-and-headings.test.tsx diff --git a/e2e/navigation-performance.spec.ts b/e2e/navigation-performance.spec.ts index 74aa3e07a..b3fb103e0 100644 --- a/e2e/navigation-performance.spec.ts +++ b/e2e/navigation-performance.spec.ts @@ -26,7 +26,7 @@ const privateRoutes = [ ['/app/attack', { selector: 'main h1', text: 'Attack' }], ['/app/flowchart', { selector: 'main h1', text: 'Argument Flowchart' }], ['/app/history', { selector: 'main h1', text: 'History' }], - ['/app/admin', { selector: 'main h3', text: 'Access Denied' }], + ['/app/admin', { selector: 'main h1', text: 'Access Denied' }], ] as const; const attackContent: ContentMarker = { selector: 'main h1', text: 'Attack' }; diff --git a/src/components/LanguageSwitcher.tsx b/src/components/LanguageSwitcher.tsx index d6e4e68c7..1b5e4aade 100644 --- a/src/components/LanguageSwitcher.tsx +++ b/src/components/LanguageSwitcher.tsx @@ -47,8 +47,8 @@ export function LanguageSwitcher() { - diff --git a/src/components/features/attack/AttackForm.tsx b/src/components/features/attack/AttackForm.tsx index ad0a8f6bd..1992a76a5 100644 --- a/src/components/features/attack/AttackForm.tsx +++ b/src/components/features/attack/AttackForm.tsx @@ -94,17 +94,19 @@ export function AttackForm({ onSubmit, isLoading, importedCase, debateContext =
- +
@@ -221,7 +221,7 @@ export function AttackResults({ result, discoveredSources, onDiscuss, onPractice
-

{t('attackResults.strengths')}

+

{t('attackResults.strengths')}

    {strengthAreas.map((strength, i) => (
  • @@ -303,12 +303,12 @@ export function AttackResults({ result, discoveredSources, onDiscuss, onPractice >
    -

    {t('attackResults.currentWeighing')}

    +

    {t('attackResults.currentWeighing')}

    {weighingAnalysis.currentWeighing}

    -

    {t('attackResults.missingComparisons')}

    +

    {t('attackResults.missingComparisons')}

      {(weighingAnalysis.missingComparisons ?? []).map((comparison, i) => (
    • @@ -320,7 +320,7 @@ export function AttackResults({ result, discoveredSources, onDiscuss, onPractice
    -

    {t('attackResults.improvements')}

    +

    {t('attackResults.improvements')}

      {(weighingAnalysis.improvementSuggestions ?? []).map((suggestion, i) => (
    • diff --git a/src/components/features/brainstorm/BrainstormResults.tsx b/src/components/features/brainstorm/BrainstormResults.tsx index 1a968aea9..3901e801c 100644 --- a/src/components/features/brainstorm/BrainstormResults.tsx +++ b/src/components/features/brainstorm/BrainstormResults.tsx @@ -44,7 +44,7 @@ function IdeaCard({ idea }: { idea: Idea }) { return (
      -

      {idea.title || t('brainstormResults.untitled')}

      +

      {idea.title || t('brainstormResults.untitled')}

      {side === 'pro' ? t('brainstormResults.pro') : side === 'con' ? t('brainstormResults.con') : t('brainstormResults.neutral')} @@ -203,10 +203,10 @@ export function BrainstormResults({ result, discoveredSources, onDiscuss }: Brai
      {result.mindmap.map((category, i) => (
      -

      +

      {category.category} -

      +
      {category.items && Array.isArray(category.items) && category.items.map((idea) => ( diff --git a/src/components/features/factoids/FactoidsResults.tsx b/src/components/features/factoids/FactoidsResults.tsx index 8ba14ec74..98e7138ac 100644 --- a/src/components/features/factoids/FactoidsResults.tsx +++ b/src/components/features/factoids/FactoidsResults.tsx @@ -54,13 +54,13 @@ function FactoidCard({ factoid, onSave }: { factoid: Factoid, onSave?: FactoidsR rel="noopener noreferrer" className="group flex items-center gap-2" > -

      +

      {factoid.shortClaim} -

      +