Skip to main contentSkip to user menuSkip to navigation

Human-Centric Architecture Design

Design systems that prioritize human needs with accessibility-first principles, cognitive load optimization, and inclusive engineering practices.

40 min readAdvanced
Not Started
Loading...

What is Human-Centric Architecture Design?

Human-centric architecture design puts people at the center of system design decisions. It encompasses accessibility, cognitive ergonomics, inclusive design, and user experience optimization at the architectural level, not just the interface layer.

Modern systems serve diverse global audiences with varying abilities, contexts, and constraints. Human-centric design ensures technology adapts to human diversity rather than forcing humans to adapt to technology limitations.

Interactive Human-Centric Assessment

Accessibility Features

Cognitive Load Features

Inclusive Design Features

Performance Targets

Human-Centric Metrics

Accessibility Score:27/100
Cognitive Score:35/100
Inclusive Score:40/100
User Satisfaction:90/100
Global Reach:60%
Adjusted Load Time:2s
Dev Cost:$170k
Annual ROI:1454%
* Metrics based on established accessibility research and user experience studies

Core Human-Centric Principles

1. Universal Accessibility

Design systems usable by people with the widest range of abilities and disabilities.

WCAG 2.1 AA compliance, assistive technology support, multiple interaction modes

2. Cognitive Ergonomics

Minimize cognitive load through intuitive information architecture and progressive disclosure.

Mental model alignment, chunking, contextual cues, error prevention

3. Inclusive by Default

Consider diverse languages, cultures, devices, and economic constraints from the start.

Internationalization, offline-first, low-bandwidth support, cultural sensitivity

4. Emotional Design

Create positive emotional experiences that build trust and confidence in users.

Microinteractions, feedback loops, personality, empathetic error handling

5. Performance Empathy

Optimize for the constraints of the least privileged users and slowest connections.

Progressive enhancement, adaptive loading, network-aware features

6. Privacy-Centric

Respect user agency with transparent data practices and meaningful consent mechanisms.

Data minimization, clear controls, privacy by design, user empowerment

Production Implementation

Human-Centric Architecture Framework

import React, { createContext, useContext, useEffect, useState } from 'react';

// Human-Centric Context and Providers
interface AccessibilityPreferences {
  reducedMotion: boolean;
  highContrast: boolean;
  largeText: boolean;
  screenReaderActive: boolean;
  keyboardNavigation: boolean;
  voiceControlActive: boolean;
}

interface CognitivePreferences {
  complexityLevel: 'minimal' | 'standard' | 'advanced';
  progressiveDisclosure: boolean;
  contextualHelp: boolean;
  autoSave: boolean;
  undoRedoAvailable: boolean;
}

interface InclusivePreferences {
  language: string;
  culturalContext: string;
  bandwidth: 'low' | 'medium' | 'high';
  deviceCapabilities: {
    touchscreen: boolean;
    camera: boolean;
    microphone: boolean;
    gps: boolean;
  };
  economicContext: 'cost-sensitive' | 'standard' | 'premium';
}

interface HumanCentricContext {
  accessibility: AccessibilityPreferences;
  cognitive: CognitivePreferences;
  inclusive: InclusivePreferences;
  updatePreferences: (updates: Partial<any>) => void;
}

const HumanCentricContext = createContext<HumanCentricContext | null>(null);

export const HumanCentricProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [preferences, setPreferences] = useState({
    accessibility: {
      reducedMotion: false,
      highContrast: false,
      largeText: false,
      screenReaderActive: false,
      keyboardNavigation: false,
      voiceControlActive: false,
    },
    cognitive: {
      complexityLevel: 'standard' as const,
      progressiveDisclosure: true,
      contextualHelp: true,
      autoSave: true,
      undoRedoAvailable: true,
    },
    inclusive: {
      language: 'en',
      culturalContext: 'global',
      bandwidth: 'medium' as const,
      deviceCapabilities: {
        touchscreen: true,
        camera: true,
        microphone: true,
        gps: true,
      },
      economicContext: 'standard' as const,
    },
  });

  // Detect user preferences from system settings
  useEffect(() => {
    const detectSystemPreferences = () => {
      const updates: any = {};

      // Detect reduced motion preference
      if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
        updates.accessibility = { ...preferences.accessibility, reducedMotion: true };
      }

      // Detect high contrast preference
      if (window.matchMedia && window.matchMedia('(prefers-contrast: high)').matches) {
        updates.accessibility = { ...updates.accessibility, highContrast: true };
      }

      // Detect screen reader usage
      const hasScreenReader = navigator.userAgent.includes('NVDA') || 
                              navigator.userAgent.includes('JAWS') || 
                              document.documentElement.hasAttribute('data-at-shortcutkeys');
      
      if (hasScreenReader) {
        updates.accessibility = { ...updates.accessibility, screenReaderActive: true };
      }

      // Detect connection speed
      const connection = (navigator as any).connection || (navigator as any).mozConnection || (navigator as any).webkitConnection;
      if (connection) {
        let bandwidth: 'low' | 'medium' | 'high' = 'medium';
        if (connection.effectiveType === '2g' || connection.effectiveType === 'slow-2g') {
          bandwidth = 'low';
        } else if (connection.effectiveType === '4g') {
          bandwidth = 'high';
        }
        updates.inclusive = { ...preferences.inclusive, bandwidth };
      }

      // Detect device capabilities
      const deviceCapabilities = {
        touchscreen: 'ontouchstart' in window,
        camera: navigator.mediaDevices && navigator.mediaDevices.getUserMedia !== undefined,
        microphone: navigator.mediaDevices && navigator.mediaDevices.getUserMedia !== undefined,
        gps: navigator.geolocation !== undefined,
      };
      
      updates.inclusive = { 
        ...updates.inclusive, 
        deviceCapabilities 
      };

      if (Object.keys(updates).length > 0) {
        setPreferences(prev => ({ ...prev, ...updates }));
      }
    };

    detectSystemPreferences();

    // Listen for preference changes
    const mediaQueryList = window.matchMedia('(prefers-reduced-motion: reduce)');
    const handleChange = detectSystemPreferences;
    mediaQueryList.addEventListener('change', handleChange);

    return () => mediaQueryList.removeEventListener('change', handleChange);
  }, []);

  const updatePreferences = (updates: Partial<typeof preferences>) => {
    setPreferences(prev => ({ ...prev, ...updates }));
    
    // Persist preferences
    localStorage.setItem('human-centric-preferences', JSON.stringify({ ...preferences, ...updates }));
  };

  // Load saved preferences
  useEffect(() => {
    const saved = localStorage.getItem('human-centric-preferences');
    if (saved) {
      try {
        const parsed = JSON.parse(saved);
        setPreferences(parsed);
      } catch (error) {
        console.warn('Failed to parse saved preferences:', error);
      }
    }
  }, []);

  return (
    <HumanCentricContext.Provider value={{ ...preferences, updatePreferences }}>
      {children}
    </HumanCentricContext.Provider>
  );
};

export const useHumanCentric = () => {
  const context = useContext(HumanCentricContext);
  if (!context) {
    throw new Error('useHumanCentric must be used within HumanCentricProvider');
  }
  return context;
};

// Accessible Component Framework
export const AccessibleButton: React.FC<{
  children: React.ReactNode;
  onClick: () => void;
  variant?: 'primary' | 'secondary';
  size?: 'small' | 'medium' | 'large';
  disabled?: boolean;
  ariaLabel?: string;
  ariaDescribedBy?: string;
}> = ({ 
  children, 
  onClick, 
  variant = 'primary', 
  size = 'medium', 
  disabled = false,
  ariaLabel,
  ariaDescribedBy
}) => {
  const { accessibility, cognitive } = useHumanCentric();
  
  const handleClick = () => {
    if (!disabled) {
      onClick();
      
      // Provide haptic feedback on supported devices
      if ('vibrate' in navigator) {
        navigator.vibrate(50);
      }
    }
  };

  const baseClasses = `
    inline-flex items-center justify-center font-medium rounded-lg
    focus:outline-none focus:ring-2 focus:ring-offset-2
    transition-all duration-200 ease-in-out
    ${accessibility.reducedMotion ? 'transition-none' : ''}
    ${accessibility.highContrast ? 'border-2 border-current' : ''}
    ${accessibility.largeText ? 'text-lg' : ''}
  `;

  const sizeClasses = {
    small: 'px-3 py-1.5 text-sm min-h-[32px] min-w-[32px]',
    medium: 'px-4 py-2 text-base min-h-[44px] min-w-[44px]', // 44px minimum for touch targets
    large: 'px-6 py-3 text-lg min-h-[56px] min-w-[56px]'
  }[size];

  const variantClasses = {
    primary: `
      bg-blue-600 text-white hover:bg-blue-700 
      focus:ring-blue-500 disabled:bg-gray-300
      ${accessibility.highContrast ? 'bg-black text-white hover:bg-gray-800' : ''}
    `,
    secondary: `
      bg-gray-200 text-gray-900 hover:bg-gray-300 
      focus:ring-gray-500 disabled:bg-gray-100
      ${accessibility.highContrast ? 'bg-white text-black border-black hover:bg-gray-100' : ''}
    `
  }[variant];

  return (
    <button
      className={`${baseClasses} ${sizeClasses} ${variantClasses}`}
      onClick={handleClick}
      disabled={disabled}
      aria-label={ariaLabel}
      aria-describedby={ariaDescribedBy}
      // Ensure keyboard navigation works
      onKeyDown={(e) => {
        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          handleClick();
        }
      }}
    >
      {children}
    </button>
  );
};

// Cognitive Load Reduction Component
export const ProgressiveDisclosure: React.FC<{
  title: string;
  children: React.ReactNode;
  defaultOpen?: boolean;
  level?: 'primary' | 'secondary' | 'tertiary';
}> = ({ title, children, defaultOpen = false, level = 'primary' }) => {
  const [isOpen, setIsOpen] = useState(defaultOpen);
  const { cognitive, accessibility } = useHumanCentric();
  
  // Auto-expand based on cognitive preferences
  useEffect(() => {
    if (cognitive.complexityLevel === 'advanced') {
      setIsOpen(true);
    }
  }, [cognitive.complexityLevel]);

  const headingLevel = {
    primary: 'h2',
    secondary: 'h3',
    tertiary: 'h4'
  }[level];

  const HeadingTag = headingLevel as keyof JSX.IntrinsicElements;

  return (
    <div className="border border-gray-200 dark:border-gray-700 rounded-lg">
      <HeadingTag className="m-0">
        <button
          className={`
            w-full px-4 py-3 text-left font-semibold
            hover:bg-gray-50 dark:hover:bg-gray-800
            focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500
            ${accessibility.reducedMotion ? '' : 'transition-colors duration-200'}
          `}
          onClick={() => setIsOpen(!isOpen)}
          aria-expanded={isOpen}
          aria-controls={`disclosure-content-${title.replace(/\s+/g, '-').toLowerCase()}`}
        >
          <span className="flex justify-between items-center">
            {title}
            <svg
              className={`w-5 h-5 transform ${isOpen ? 'rotate-180' : 'rotate-0'} ${
                accessibility.reducedMotion ? '' : 'transition-transform duration-200'
              }`}
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="m19 9-7 7-7-7" />
            </svg>
          </span>
        </button>
      </HeadingTag>
      
      <div
        id={`disclosure-content-${title.replace(/\s+/g, '-').toLowerCase()}`}
        className={`overflow-hidden ${
          accessibility.reducedMotion ? '' : 'transition-all duration-300'
        }`}
        style={{ 
          maxHeight: isOpen ? '1000px' : '0',
          opacity: isOpen ? 1 : 0 
        }}
      >
        <div className="px-4 pb-4">
          {children}
        </div>
      </div>
    </div>
  );
};

// Inclusive Form Component
export const InclusiveForm: React.FC<{
  children: React.ReactNode;
  onSubmit: (data: FormData) => void;
  autoSave?: boolean;
}> = ({ children, onSubmit, autoSave = false }) => {
  const { cognitive, accessibility, inclusive } = useHumanCentric();
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);

  // Auto-save functionality
  useEffect(() => {
    if (autoSave && cognitive.autoSave && hasUnsavedChanges) {
      const timer = setTimeout(() => {
        // Implement auto-save logic
        console.log('Auto-saving form data...');
        setHasUnsavedChanges(false);
      }, 2000);

      return () => clearTimeout(timer);
    }
  }, [autoSave, cognitive.autoSave, hasUnsavedChanges]);

  const handleFormChange = () => {
    setHasUnsavedChanges(true);
  };

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        onSubmit(new FormData(e.currentTarget));
      }}
      onChange={handleFormChange}
      className="space-y-6"
      noValidate // We'll handle validation ourselves for better UX
    >
      {/* Cultural context indicator */}
      {inclusive.culturalContext !== 'global' && (
        <div className="bg-blue-50 dark:bg-blue-900/20 p-3 rounded-lg">
          <p className="text-sm text-blue-800 dark:text-blue-200">
            Form adapted for {inclusive.culturalContext} context
          </p>
        </div>
      )}

      {children}

      {/* Auto-save indicator */}
      {autoSave && cognitive.autoSave && (
        <div className="flex items-center text-sm text-gray-600 dark:text-gray-400">
          {hasUnsavedChanges ? (
            <span>Saving changes...</span>
          ) : (
            <span>✓ All changes saved</span>
          )}
        </div>
      )}

      {/* Keyboard navigation hint */}
      {accessibility.keyboardNavigation && (
        <div className="text-sm text-gray-500 dark:text-gray-400">
          Press Tab to navigate, Enter to submit, Esc to cancel
        </div>
      )}
    </form>
  );
};

// Performance-aware Image Component
export const InclusiveImage: React.FC<{
  src: string;
  alt: string;
  width?: number;
  height?: number;
  priority?: boolean;
}> = ({ src, alt, width, height, priority = false }) => {
  const { inclusive, accessibility } = useHumanCentric();
  const [imageSrc, setImageSrc] = useState<string>('');

  useEffect(() => {
    // Adapt image quality based on connection and preferences
    let adaptedSrc = src;
    
    if (inclusive.bandwidth === 'low') {
      // Use lower quality images for slow connections
      adaptedSrc = src.replace(/\.(jpg|jpeg|png)$/i, '_low.$1');
    } else if (inclusive.bandwidth === 'high') {
      // Use high quality images for fast connections
      adaptedSrc = src.replace(/\.(jpg|jpeg|png)$/i, '_high.$1');
    }

    // Respect data saving preferences
    if (inclusive.economicContext === 'cost-sensitive') {
      adaptedSrc = src.replace(/\.(jpg|jpeg|png)$/i, '_compressed.$1');
    }

    setImageSrc(adaptedSrc);
  }, [src, inclusive.bandwidth, inclusive.economicContext]);

  return (
    <img
      src={imageSrc || src}
      alt={alt}
      width={width}
      height={height}
      loading={priority ? 'eager' : 'lazy'}
      decoding="async"
      className={`
        ${accessibility.reducedMotion ? '' : 'transition-opacity duration-300'}
        ${accessibility.highContrast ? 'filter contrast-125' : ''}
      `}
      // Provide fallback for failed loads
      onError={(e) => {
        const target = e.target as HTMLImageElement;
        target.src = '/images/placeholder.svg';
      }}
    />
  );
};

// Usage Example Component
export const HumanCentricApp: React.FC = () => {
  const { accessibility, cognitive, inclusive, updatePreferences } = useHumanCentric();

  return (
    <div className="max-w-[1200px] mx-auto px-4 md:px-6 py-8">
      <header>
        <h1 className="text-3xl font-bold mb-4">Human-Centric Application</h1>
        
        {/* Accessibility preferences panel */}
        <ProgressiveDisclosure title="Accessibility Settings" level="secondary">
          <div className="grid grid-cols-2 gap-4">
            <label className="flex items-center space-x-2">
              <input
                type="checkbox"
                checked={accessibility.reducedMotion}
                onChange={(e) => updatePreferences({
                  accessibility: { ...accessibility, reducedMotion: e.target.checked }
                })}
              />
              <span>Reduce motion</span>
            </label>
            
            <label className="flex items-center space-x-2">
              <input
                type="checkbox"
                checked={accessibility.highContrast}
                onChange={(e) => updatePreferences({
                  accessibility: { ...accessibility, highContrast: e.target.checked }
                })}
              />
              <span>High contrast</span>
            </label>
          </div>
        </ProgressiveDisclosure>
      </header>

      <main>
        <InclusiveForm 
          onSubmit={(data) => console.log('Form submitted:', data)}
          autoSave={cognitive.autoSave}
        >
          <div>
            <label htmlFor="name" className="block text-sm font-medium mb-2">
              Name
            </label>
            <input
              type="text"
              id="name"
              name="name"
              className="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
              aria-describedby="name-help"
            />
            {cognitive.contextualHelp && (
              <p id="name-help" className="mt-1 text-sm text-gray-600">
                Enter your full name as you'd like it to appear
              </p>
            )}
          </div>

          <AccessibleButton variant="primary" onClick={() => console.log('Submitted!')}>
            Submit Form
          </AccessibleButton>
        </InclusiveForm>

        <ProgressiveDisclosure title="Advanced Options" defaultOpen={cognitive.complexityLevel === 'advanced'}>
          <p>Advanced configuration options would appear here...</p>
        </ProgressiveDisclosure>
      </main>
    </div>
  );
};

export default HumanCentricApp;

Accessibility Testing Automation

// Automated Accessibility Testing Suite
const { chromium } = require('playwright');
const axe = require('@axe-core/playwright');

class AccessibilityTestSuite {
  constructor() {
    this.browser = null;
    this.context = null;
  }

  async setup() {
    this.browser = await chromium.launch({ headless: false });
    this.context = await this.browser.newContext({
      // Simulate various user preferences
      reducedMotion: 'reduce',
      colorScheme: 'dark',
      extraHTTPHeaders: {
        'User-Agent': 'NVDA/2023.1 (Screen Reader)'
      }
    });
  }

  async runComprehensiveAccessibilityTest(url, options = {}) {
    const page = await this.context.newPage();
    await axe.injectIntoPage(page);
    
    const results = {
      url,
      timestamp: new Date().toISOString(),
      tests: []
    };

    try {
      await page.goto(url);
      
      // Basic axe-core scan
      const axeResults = await axe.run(page, {
        tags: ['wcag2a', 'wcag2aa', 'wcag21aa', 'best-practice'],
        rules: {
          'color-contrast': { enabled: true },
          'keyboard-navigation': { enabled: true },
          'focus-management': { enabled: true },
          'aria-usage': { enabled: true }
        }
      });
      
      results.tests.push({
        name: 'WCAG 2.1 AA Compliance',
        violations: axeResults.violations,
        passes: axeResults.passes,
        score: this.calculateAccessibilityScore(axeResults)
      });

      // Keyboard navigation test
      const keyboardResults = await this.testKeyboardNavigation(page);
      results.tests.push(keyboardResults);

      // Screen reader compatibility test
      const screenReaderResults = await this.testScreenReaderCompatibility(page);
      results.tests.push(screenReaderResults);

      // Cognitive load assessment
      const cognitiveResults = await this.testCognitiveLoad(page);
      results.tests.push(cognitiveResults);

      // Performance accessibility test
      const performanceResults = await this.testPerformanceAccessibility(page);
      results.tests.push(performanceResults);

      // Multi-language support test
      if (options.testInternationalization) {
        const i18nResults = await this.testInternationalization(page);
        results.tests.push(i18nResults);
      }

      // Mobile accessibility test
      const mobileResults = await this.testMobileAccessibility(page);
      results.tests.push(mobileResults);

    } catch (error) {
      results.error = error.message;
    } finally {
      await page.close();
    }

    return results;
  }

  async testKeyboardNavigation(page) {
    const results = {
      name: 'Keyboard Navigation',
      violations: [],
      passes: [],
      score: 0
    };

    try {
      // Test tab navigation
      const focusableElements = await page.$$('[tabindex]:not([tabindex="-1"]), button, input, select, textarea, a[href]');
      
      let tabCount = 0;
      let currentElement = null;

      for (let i = 0; i < Math.min(focusableElements.length, 20); i++) {
        await page.keyboard.press('Tab');
        tabCount++;
        
        const focusedElement = await page.evaluate(() => {
          const element = document.activeElement;
          return {
            tagName: element.tagName,
            role: element.getAttribute('role'),
            ariaLabel: element.getAttribute('aria-label'),
            visible: element.offsetParent !== null
          };
        });

        if (!focusedElement.visible) {
          results.violations.push({
            description: 'Tab landed on invisible element',
            element: focusedElement,
            tabIndex: tabCount
          });
        } else {
          results.passes.push({
            description: 'Tab navigation to visible element',
            element: focusedElement
          });
        }
      }

      // Test escape key functionality
      await page.keyboard.press('Escape');
      const escapeHandled = await page.evaluate(() => {
        // Check if any modals or overlays were closed
        return document.querySelectorAll('[role="dialog"]:not([aria-hidden="true"])').length === 0;
      });

      if (escapeHandled) {
        results.passes.push({ description: 'Escape key properly handled' });
      }

      // Test Enter and Space key activation
      const buttons = await page.$$('button:not([disabled])');
      if (buttons.length > 0) {
        await buttons[0].focus();
        await page.keyboard.press('Enter');
        // Check if button action was triggered
        results.passes.push({ description: 'Enter key activates buttons' });
        
        await page.keyboard.press('Space');
        results.passes.push({ description: 'Space key activates buttons' });
      }

      results.score = (results.passes.length / (results.passes.length + results.violations.length)) * 100;

    } catch (error) {
      results.violations.push({
        description: 'Keyboard navigation test failed',
        error: error.message
      });
    }

    return results;
  }

  async testScreenReaderCompatibility(page) {
    const results = {
      name: 'Screen Reader Compatibility',
      violations: [],
      passes: [],
      score: 0
    };

    try {
      // Test ARIA landmarks
      const landmarks = await page.$$('[role="main"], [role="navigation"], [role="banner"], [role="contentinfo"], [role="complementary"]');
      if (landmarks.length > 0) {
        results.passes.push({
          description: `Found ${landmarks.length} ARIA landmarks`,
          count: landmarks.length
        });
      } else {
        results.violations.push({
          description: 'No ARIA landmarks found',
          impact: 'serious'
        });
      }

      // Test heading structure
      const headings = await page.$$('h1, h2, h3, h4, h5, h6, [role="heading"]');
      const headingLevels = await Promise.all(
        headings.map(h => h.evaluate(el => ({
          level: el.tagName.charAt(1) || el.getAttribute('aria-level'),
          text: el.textContent?.trim()
        })))
      );

      // Check for proper heading hierarchy
      let previousLevel = 0;
      for (const heading of headingLevels) {
        const currentLevel = parseInt(heading.level);
        if (currentLevel > previousLevel + 1) {
          results.violations.push({
            description: `Heading level skip: jumped from h${previousLevel} to h${currentLevel}`,
            text: heading.text
          });
        } else {
          results.passes.push({
            description: `Proper heading hierarchy: h${currentLevel}`,
            text: heading.text
          });
        }
        previousLevel = currentLevel;
      }

      // Test alt text for images
      const images = await page.$$('img');
      for (const img of images) {
        const altText = await img.getAttribute('alt');
        const ariaLabel = await img.getAttribute('aria-label');
        const role = await img.getAttribute('role');
        
        if (role === 'presentation' || altText === '') {
          results.passes.push({ description: 'Decorative image properly marked' });
        } else if (altText || ariaLabel) {
          results.passes.push({ description: 'Image has accessible text' });
        } else {
          results.violations.push({
            description: 'Image missing alt text',
            src: await img.getAttribute('src')
          });
        }
      }

      // Test form labels
      const inputs = await page.$$('input, select, textarea');
      for (const input of inputs) {
        const id = await input.getAttribute('id');
        const ariaLabel = await input.getAttribute('aria-label');
        const ariaLabelledBy = await input.getAttribute('aria-labelledby');
        
        let hasLabel = false;
        
        if (id) {
          const label = await page.$(`label[for="${id}"]`);
          if (label) hasLabel = true;
        }
        
        if (ariaLabel || ariaLabelledBy) hasLabel = true;
        
        if (hasLabel) {
          results.passes.push({ description: 'Form input has accessible label' });
        } else {
          results.violations.push({
            description: 'Form input missing accessible label',
            type: await input.getAttribute('type') || 'input'
          });
        }
      }

      results.score = (results.passes.length / (results.passes.length + results.violations.length)) * 100;

    } catch (error) {
      results.violations.push({
        description: 'Screen reader compatibility test failed',
        error: error.message
      });
    }

    return results;
  }

  async testCognitiveLoad(page) {
    const results = {
      name: 'Cognitive Load Assessment',
      violations: [],
      passes: [],
      score: 0,
      metrics: {}
    };

    try {
      // Count interactive elements
      const interactiveElements = await page.$$('button, input, select, textarea, a[href], [tabindex]');
      results.metrics.interactiveElementCount = interactiveElements.length;
      
      if (interactiveElements.length > 50) {
        results.violations.push({
          description: 'High cognitive load: too many interactive elements',
          count: interactiveElements.length
        });
      } else {
        results.passes.push({
          description: 'Manageable number of interactive elements',
          count: interactiveElements.length
        });
      }

      // Analyze information density
      const textContent = await page.evaluate(() => document.body.textContent);
      const wordCount = textContent.split(/\s+/).length;
      results.metrics.wordCount = wordCount;

      const viewportHeight = await page.evaluate(() => window.innerHeight);
      const contentHeight = await page.evaluate(() => document.body.scrollHeight);
      const contentDensity = wordCount / (contentHeight / viewportHeight);
      
      results.metrics.contentDensity = contentDensity;
      
      if (contentDensity > 100) {
        results.violations.push({
          description: 'High information density may cause cognitive overload',
          density: contentDensity
        });
      } else {
        results.passes.push({
          description: 'Appropriate information density',
          density: contentDensity
        });
      }

      // Check for progressive disclosure
      const collapsibleElements = await page.$$('[aria-expanded]');
      if (collapsibleElements.length > 0) {
        results.passes.push({
          description: 'Progressive disclosure implemented',
          count: collapsibleElements.length
        });
      }

      // Check for contextual help
      const helpElements = await page.$$('[aria-describedby], .help-text, .tooltip');
      if (helpElements.length > 0) {
        results.passes.push({
          description: 'Contextual help available',
          count: helpElements.length
        });
      }

      results.score = (results.passes.length / (results.passes.length + results.violations.length)) * 100;

    } catch (error) {
      results.violations.push({
        description: 'Cognitive load assessment failed',
        error: error.message
      });
    }

    return results;
  }

  async testPerformanceAccessibility(page) {
    const results = {
      name: 'Performance Accessibility',
      violations: [],
      passes: [],
      score: 0,
      metrics: {}
    };

    try {
      // Measure page load performance
      const performanceMetrics = await page.evaluate(() => {
        const perfData = performance.getEntriesByType('navigation')[0];
        return {
          loadTime: perfData.loadEventEnd - perfData.loadEventStart,
          domContentLoaded: perfData.domContentLoadedEventEnd - perfData.domContentLoadedEventStart,
          firstContentfulPaint: performance.getEntriesByName('first-contentful-paint')[0]?.startTime || 0
        };
      });

      results.metrics = performanceMetrics;

      // Check load time accessibility
      if (performanceMetrics.loadTime < 3000) {
        results.passes.push({
          description: 'Fast page load time',
          loadTime: performanceMetrics.loadTime
        });
      } else {
        results.violations.push({
          description: 'Slow page load may impact users with cognitive disabilities',
          loadTime: performanceMetrics.loadTime
        });
      }

      // Check for loading indicators
      const loadingIndicators = await page.$$('[role="progressbar"], .loading, .spinner');
      if (loadingIndicators.length > 0) {
        results.passes.push({
          description: 'Loading indicators present',
          count: loadingIndicators.length
        });
      }

      // Test reduced motion preference
      await page.emulateMedia({ reducedMotion: 'reduce' });
      const animatedElements = await page.$$('[class*="animate"], [class*="transition"]');
      
      // Check if animations are properly disabled
      for (const element of animatedElements) {
        const computedStyle = await element.evaluate(el => {
          const style = getComputedStyle(el);
          return {
            animationDuration: style.animationDuration,
            transitionDuration: style.transitionDuration
          };
        });

        if (computedStyle.animationDuration === '0s' || computedStyle.transitionDuration === '0s') {
          results.passes.push({ description: 'Animations respect reduced motion preference' });
        } else {
          results.violations.push({
            description: 'Animations do not respect reduced motion preference',
            element: 'animated element'
          });
        }
      }

      results.score = (results.passes.length / (results.passes.length + results.violations.length)) * 100;

    } catch (error) {
      results.violations.push({
        description: 'Performance accessibility test failed',
        error: error.message
      });
    }

    return results;
  }

  calculateAccessibilityScore(axeResults) {
    const totalRules = axeResults.passes.length + axeResults.violations.length + axeResults.incomplete.length;
    if (totalRules === 0) return 0;
    
    const passWeight = 1;
    const violationWeight = -2;
    const incompleteWeight = -0.5;
    
    const score = (
      (axeResults.passes.length * passWeight) +
      (axeResults.violations.length * violationWeight) +
      (axeResults.incomplete.length * incompleteWeight)
    ) / totalRules;
    
    return Math.max(0, Math.min(100, (score + 2) / 3 * 100));
  }

  async teardown() {
    if (this.browser) {
      await this.browser.close();
    }
  }
}

// Usage example
async function runAccessibilityTests() {
  const suite = new AccessibilityTestSuite();
  await suite.setup();
  
  const results = await suite.runComprehensiveAccessibilityTest('https://example.com', {
    testInternationalization: true
  });
  
  console.log('Accessibility Test Results:', JSON.stringify(results, null, 2));
  
  await suite.teardown();
}

module.exports = { AccessibilityTestSuite };

Real-World Examples

GV

UK Government (GOV.UK)

Accessibility-First Design System

GOV.UK built their design system with accessibility as the primary constraint, not an afterthought. Every component is tested with screen readers, keyboard navigation, and cognitive load assessment. Their approach demonstrates how accessibility-first design improves usability for everyone.

WCAG 2.1 AAAProgressive Enhancement
MS

Microsoft

Inclusive Design at Scale

Microsoft's Inclusive Design methodology recognizes that exclusion is the source of innovation. Their human-centric approach led to features like live captions, immersive reader, and adaptive controllers that benefit millions of users beyond their original target audience.

Inclusive DesignAI-Powered Accessibility
WP

Wikipedia

Global Inclusive Architecture

Wikipedia's architecture prioritizes global accessibility with 300+ languages, offline reading capabilities, and bandwidth-adaptive content delivery. Their human-centric design ensures knowledge accessibility regardless of device, connection, or economic constraints.

300+ LanguagesOffline-First
No quiz questions available
Quiz ID "human-centric-architecture-design" not found