-
Notifications
You must be signed in to change notification settings - Fork 81
Accessibility
This document tracks comprehensive accessibility improvements made to GroqTales to ensure WCAG 2.1 AA compliance and inclusive UI for all users.
-
File:
app/layout.tsx - Added keyboard-accessible skip link to jump directly to main content
- Implemented
.skip-linkand.sr-onlyutility classes - Skip link becomes visible on keyboard focus
-
File:
app/globals.css - Added visible focus outlines (3px solid) for all interactive elements
- Focus indicators meet WCAG 2.1 AA contrast requirements
- Applied to: links, buttons, inputs, selects, textareas
- Offset: 3px for clear visibility
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: 3px solid var(--ring);
outline-offset: 3px;
}-
File:
components/header.tsx - Added
role="navigation"andaria-label="Primary navigation" - Implemented
aria-current="page"for active navigation links - Added
aria-haspopup="true"for dropdown triggers - Logo link has descriptive
aria-label="GroqTales home" - Create button has
aria-label="Create a new story"
-
File:
components/footer.tsx - Added
role="contentinfo"to footer element - Each footer section (Explore, Legal, Resources) wrapped in
<nav>with descriptivearia-label - Social media links section has
role="group"andaria-label="Social media links" - All external links have
aria-labelwith platform name
-
Mode Toggle (
components/mode-toggle.tsx):aria-label="Toggle theme" -
User Navigation (
components/user-nav.tsx):- Dropdown trigger:
aria-label="User menu" - Login button:
aria-label="Connect wallet to login"
- Dropdown trigger:
-
Wallet Connect (
components/wallet-connect.tsx):- Connect button:
aria-labelchanges based on connection state - Dropdown trigger: Shows connected wallet address in label
- Avatar has descriptive alt text with truncated address
- Connect button:
-
Back to Top (
components/back-to-top.tsx):- Button:
aria-label="Scroll back to top" - Hidden from screen readers when not visible:
aria-hidden={!visible} - Decorative SVG marked with
aria-hidden="true"
- Button:
-
Create Story Dialog (
components/create-story-dialog.tsx):- Dialog has
aria-describedbylinking to description text - Story type buttons have
aria-pressedstate - Back button:
aria-label="Go back to story type selection" - Option buttons include full description in
aria-label - Decorative icons marked with
aria-hidden="true"
- Dialog has
All avatar images now include descriptive alt text:
- User avatars:
alt="${username}'s avatar" - Profile pictures:
alt="${name}'s profile picture" - Identicon avatars:
alt="Identicon for wallet address ${address}"
Files Updated:
-
components/story-card.tsx- Story author avatars -
components/wallet-connect.tsx- Wallet identicon -
app/community/creators/page.tsx- Creator profile pictures -
app/stories/[id]/page.tsx- Comment author avatars and creator profiles -
app/nft-marketplace/comic-stories/page.tsx- Comic author avatars
- Story cover images include story title in alt text
- NFT images include NFT title in alt text
- Profile settings images:
alt="Profile picture"
- Icons used purely for decoration marked with
aria-hidden="true" - Status indicators (verified badges, etc.) have appropriate labels
All buttons now have:
- Descriptive
aria-labelwhen text content is not sufficient - Proper button role (native
<button>elements used) - Keyboard accessibility (Enter and Space key support)
Examples:
- View NFT buttons:
aria-label="View NFT: {story.title}" - Comment buttons:
aria-label="View {count} comments for {story.title}" - Create similar:
aria-label="Create a story similar to {story.title}"
- All links have accessible names (visible text or aria-label)
- External links marked with
rel="noopener noreferrer" - Social media links have platform names in
aria-label
File: app/globals.css
.sr-only {
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);
white-space: nowrap;
}Used for:
- Screen reader-only text
- Skip link when not focused
- Hidden labels for icon-only buttons
- Proper heading hierarchy (h1 → h2 → h3)
- Landmark regions:
<header>,<nav>,<main>,<footer> - Lists use proper
<ul>,<ol>, and<li>elements
- 1.1.1 Non-text Content (A): All images have alt text
- 1.3.1 Info and Relationships (A): Semantic HTML and ARIA labels
- 1.4.3 Contrast (AA): Focus indicators meet 3:1 contrast ratio
- 1.4.11 Non-text Contrast (AA): Interactive elements have sufficient contrast
- 2.1.1 Keyboard (A): All functionality available via keyboard
- 2.1.2 No Keyboard Trap (A): No keyboard traps in dialogs or dropdowns
- 2.4.1 Bypass Blocks (A): Skip link implemented
- 2.4.3 Focus Order (A): Logical tab order
- 2.4.7 Focus Visible (AA): Visible focus indicators on all interactive elements
- 3.2.4 Consistent Identification (AA): Consistent UI patterns
- 3.3.2 Labels or Instructions (A): Form inputs have labels
- 4.1.2 Name, Role, Value (A): All interactive elements have accessible names
- 4.1.3 Status Messages (AA): Toast notifications announce updates
Run the following tools to verify improvements:
# Install dependencies (if not already installed)
npm install -D @axe-core/cli lighthouse
# Run axe accessibility tests
npx axe https://groqtales.xyz --save axe-report.json
# Run Lighthouse accessibility audit
npx lighthouse https://groqtales.xyz --only-categories=accessibility --output=html --output-path=./lighthouse-report.html-
Keyboard Navigation:
- Tab through all interactive elements
- Verify focus indicators are visible
- Test skip link (Tab on page load)
- Ensure dropdowns open/close with Enter/Space
-
Screen Reader Testing:
- NVDA (Windows): Test with Firefox
- JAWS (Windows): Test with Chrome
- VoiceOver (macOS): Test with Safari
- Verify all images have announced alt text
- Check landmark navigation works
-
Color Contrast:
- Use browser DevTools to verify contrast ratios
- Test in both light and dark modes
-
app/layout.tsx- Skip link added -
app/globals.css- Focus styles, sr-only, skip-link utilities
-
components/header.tsx- Navigation ARIA labels -
components/footer.tsx- Semantic navigation, ARIA roles -
components/mode-toggle.tsx- Theme toggle accessibility -
components/user-nav.tsx- User menu accessibility -
components/wallet-connect.tsx- Wallet connection accessibility -
components/create-story-dialog.tsx- Dialog accessibility -
components/back-to-top.tsx- Button accessibility -
components/story-card.tsx- Card component accessibility
-
app/community/creators/page.tsx- Creator avatars alt text -
app/stories/[id]/page.tsx- Story detail accessibility -
app/nft-marketplace/comic-stories/page.tsx- Comic cards accessibility
-
Broader User Base: Platform is now accessible to users with:
- Visual impairments (screen reader users)
- Motor impairments (keyboard-only navigation)
- Cognitive impairments (clear focus indicators, semantic structure)
-
SEO Improvements: Better semantic HTML and alt text improves search engine indexing
-
Legal Compliance: Meets WCAG 2.1 AA standards, reducing legal risk
-
Better UX for Everyone: Clear focus indicators, logical navigation, and semantic structure benefit all users
- Regular Audits: Run automated accessibility tests in CI/CD pipeline
- User Testing: Conduct testing with actual users who rely on assistive technologies
- Documentation: Keep accessibility guidelines in project documentation
- Training: Ensure all developers understand accessibility best practices
- Continuous Improvement: Monitor and address accessibility issues as they arise
GroqTales is an AI-powered Web3 storytelling platform that enables users to create, share, and monetize stories using artificial intelligence and blockchain technology. Join us to revolutionize digital storytelling!
© 2026 GroqTales. @Indie Hub - All rights reserved. Built with ❤️ for storytellers and creators.

Welcome to the GroqTales Wiki! Use the links below to explore our comprehensive documentation.
Navigation designed for GroqTales Wiki users and contributors.