tractatus/public/js/researcher-page.js
TheFlow 7a4603b3a6 feat(researcher): WCAG compliance, Berlin/Weil foundations, fixed footer i18n
- 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>
2025-10-22 23:56:37 +13:00

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');
}
}
});