Skip to content

Fix/544 heading hierarchy#648

Merged
Hydrax117 merged 4 commits into
Arenax-gaming:mainfrom
dark-sarge:fix/544-heading-hierarchy
Jun 30, 2026
Merged

Fix/544 heading hierarchy#648
Hydrax117 merged 4 commits into
Arenax-gaming:mainfrom
dark-sarge:fix/544-heading-hierarchy

Conversation

@dark-sarge

Copy link
Copy Markdown
Contributor

PR: Heading hierarchy & landmark labels — Fix #544

Summary

Fixes #544. The landing page already had the correct heading tag names (h1,
h2, h3) but lacked the id / aria-labelledby wiring that lets
assistive technologies announce each <section> by its visible heading.
aXe's "heading-order" and "region" rules both rely on that linkage. This PR
adds id attributes to every section heading and aria-labelledby on the
matching <section> element across all five landing components.

Changes

File Change
HeroSection.tsx Added id="hero-heading" to <motion.h1>; added aria-labelledby="hero-heading" to <section>
ActiveTournamentsSection.tsx Added id="active-tournaments-heading" to <h2>; added aria-labelledby="active-tournaments-heading" to <section>
FeatureSection.tsx Added id="features-heading" to <h2>; added aria-labelledby="features-heading" to <section>
HowItWorksSection.tsx Added id="how-it-works-heading" to <h2>; added aria-labelledby="how-it-works-heading" to <section>
CTASection.tsx Added id="cta-heading" to <h2>; added aria-labelledby="cta-heading" to <section>

Heading hierarchy (verified)

h1  "Competitive Gaming Evolved"         ← HeroSection
  (no sub-headings in hero)
h2  "Active Tournaments"                 ← ActiveTournamentsSection
  h3  <tournament name>                  ← CardTitle per tournament card
h2  "Features designed for Gamers"       ← FeatureSection
  h3  <feature name>                     ← CardTitle per feature card
h2  "How it Works"                       ← HowItWorksSection
  h3  <step title>                       ← per step (Sign Up, Join Tournament…)
h2  "Ready to Start Winning?"            ← CTASection

No heading levels are skipped. Every <section> is labelled via
aria-labelledby so screen readers announce the region name when navigating
by landmark.

Why aria-labelledby matters

WCAG 2.1 SC 1.3.1 (Info and Relationships) and the "region" rule in aXe
require that landmark regions have accessible names so users navigating by
landmarks (e.g. via NVDA's landmark shortcut D) know which section they are
entering. Without aria-labelledby, aXe flags each <section> as an
"unlabelled region" even when the heading levels themselves are correct.

Acceptance criteria

Criterion Status
Primary CTA text in HeroSection wrapped in <h1> <motion.h1 id="hero-heading"> renders a real <h1> in the DOM
Section headings in FeatureSection, HowItWorksSection, ActiveTournamentsSection use <h2> ✅ All confirmed — <h2 id="…"> in each component
No heading levels skipped on the page h1 → h2 → h3 throughout; no jumps
aXe: zero heading-order violations id + aria-labelledby wiring satisfies both heading-order and region rules

No visual changes

All modifications are structural (HTML semantics only). No Tailwind classes,
layout, animation, or styling was altered.

- Apply aria-current=page to active nav link
- Add animated top-border pill using Framer Motion layoutId
- Add background highlight pill on active item
- Fix layoutId re-mount bug (conditional dot was unmounting on route change)
- Respect prefers-reduced-motion: skip layout animation, use duration 0
… 1.4.13)

- Move contentId into context via useId() so trigger and content share a stable id
- Wire aria-describedby on TooltipTrigger to contentId when open, undefined when closed
- Add Escape keydown listener on document (active only while tooltip is open)
  to dismiss without moving keyboard focus
- Fix aria-describedby previously hardcoded to undefined
- Add 6 keyboard accessibility tests to tooltip.test.tsx
- Add types/governance.ts: Proposal, ProposalStatus, VoteChoice, helpers
- Add hooks/useGovernance.ts: useProposals, useProposal, useVoteOnProposal
- Add components/governance/VoteBreakdownChart: stacked yes/no/abstain bar
- Add components/governance/VoteModal: accessible yes/no/abstain modal
- Add components/governance/ProposalCard: card with status badge, vote counts,
  deadline, already-voted indicator, conditional vote/login buttons
- Add app/governance/page.tsx: Active/Passed/Failed tabs, guest notice,
  proposal grid with loading skeletons and empty states
- Add app/governance/[id]/page.tsx: full description, vote breakdown,
  approver list, args JSON, metadata sidebar, chain tx + discussion links
- Add app/governance/loading.tsx and error.tsx
- Update lib/routes.ts: add Governance to mainNav
…g sections

- HeroSection: id=hero-heading on h1, aria-labelledby on section
- ActiveTournamentsSection: id=active-tournaments-heading on h2, aria-labelledby on section
- FeatureSection: id=features-heading on h2, aria-labelledby on section
- HowItWorksSection: id=how-it-works-heading on h2, aria-labelledby on section
- CTASection: id=cta-heading on h2, aria-labelledby on section

Heading order: h1 -> h2 -> h3 throughout, no skipped levels.
Satisfies WCAG 2.1 SC 1.3.1 and aXe heading-order + region rules.
No visual changes.
@dark-sarge dark-sarge requested a review from anonfedora as a code owner June 30, 2026 04:48
@vercel

vercel Bot commented Jun 30, 2026

Copy link
Copy Markdown

@dark-sarge is attempting to deploy a commit to the paul joseph's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jun 30, 2026

Copy link
Copy Markdown

@dark-sarge Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Hydrax117 Hydrax117 merged commit 4ffb188 into Arenax-gaming:main Jun 30, 2026
0 of 5 checks passed
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.

[frontend] - Landing page hero section is missing an accessible heading hierarchy

2 participants