- Full WCAG accessibility: ARIA attributes (aria-expanded, aria-controls), keyboard navigation (Enter/Space)
- Reframed research context: Berlin/Weil as primary intellectual foundation (moral pluralism, categorical imperative)
- Bibliography with proper academic citations: Weil (The Need for Roots, Gravity and Grace), Berlin (Four Essays on Liberty)
- Fixed footer i18n: Implemented recursive deepMerge() to preserve nested translation objects
- Root cause: Shallow merge {...obj1, ...obj2} was overwriting entire footer object from common.json
- Consolidated all footer translations in common.json, removed from page-specific files
- Mobile optimization: 44px/48px touch targets, touch-action: manipulation, responsive design
- Progressive enhancement: <noscript> fallback for JavaScript-disabled users
- Version 1.3.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
48 lines
1.5 KiB
JavaScript
48 lines
1.5 KiB
JavaScript
/**
|
|
* Researcher Page - Accordion Functionality
|
|
* Handles expandable/collapsible sections for research content
|
|
* Implements WAI-ARIA Authoring Practices for accordions
|
|
*/
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Get all accordion buttons
|
|
const accordionButtons = document.querySelectorAll('[data-accordion]');
|
|
|
|
accordionButtons.forEach(button => {
|
|
// Click handler
|
|
button.addEventListener('click', function() {
|
|
const accordionId = this.dataset.accordion;
|
|
toggleAccordion(accordionId, this);
|
|
});
|
|
|
|
// Keyboard handler (Enter and Space)
|
|
button.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
e.preventDefault();
|
|
const accordionId = this.dataset.accordion;
|
|
toggleAccordion(accordionId, this);
|
|
}
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Toggle accordion section open/closed
|
|
* @param {string} id - Accordion section ID
|
|
* @param {HTMLElement} button - The button element that triggered toggle
|
|
*/
|
|
function toggleAccordion(id, button) {
|
|
const content = document.getElementById(id + '-content');
|
|
const icon = document.getElementById(id + '-icon');
|
|
|
|
if (content && icon) {
|
|
const isExpanded = content.classList.contains('active');
|
|
|
|
// Toggle CSS classes for visual state
|
|
content.classList.toggle('active');
|
|
icon.classList.toggle('active');
|
|
|
|
// Update ARIA state
|
|
button.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');
|
|
}
|
|
}
|
|
});
|