Major changes to /researcher.html:
- Replace generic limitations with validated vs not validated structure
- Add grounded evidence for 5 validated capabilities (1,130+ audit logs, 62 instructions, 500 sessions)
- Honest disclosure of 8 research gaps with specific methodology needs
- Add Research Collaboration Opportunities section (8 concrete research questions RQ1-RQ8)
- Add research inquiry modal (9 form fields, awakening not recruitment approach)
- Update i18n with 170+ new keys across EN/DE/FR
Validated capabilities:
- Architectural blocking mechanisms functional
- Instruction persistence in single-session context
- Audit trails capture governance decisions
- Context pressure monitoring operational
- Single-project governance successful
Research gaps disclosed:
- Multi-organization deployments
- Adversarial robustness
- Cross-platform consistency
- Concurrent session architecture
- Rule proliferation impact
- Regulatory evidence sufficiency
- Values pluralism in practice
- Enterprise scale performance
Research collaboration features:
- 8 prioritized research questions (high/medium/low priority)
- Methodology specifications for each RQ
- "What we can offer" vs "What we cannot provide" (honest boundaries)
- Research inquiry modal (NOT user acquisition)
- Form validates methodological rigor focus
Cultural DNA compliance:
- inst_086: Honest uncertainty disclosure (validated vs unknown)
- inst_088: Awakening over recruiting (research partners, not users)
- inst_085: Grounded operational language (evidence-based claims)
- inst_017: Fixed absolute assurance terms ("guarantees" → "properties", "Guaranteed" → "Assured")
Translation: All 170+ new keys translated to German and French via DeepL API
Files modified:
- public/researcher.html: +260 lines (limitations, research collab, modal)
- public/js/researcher-page.js: +113 lines (modal functionality)
- public/locales/en/researcher.json: +170 keys
- public/locales/de/researcher.json: +170 keys (DeepL)
- public/locales/fr/researcher.json: +170 keys (DeepL)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
165 lines
5.2 KiB
JavaScript
165 lines
5.2 KiB
JavaScript
/**
|
|
* Researcher Page - Accordion & Research Inquiry Modal
|
|
* Handles expandable/collapsible sections and research inquiry modal
|
|
* Implements WAI-ARIA Authoring Practices for accordions
|
|
*/
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// ============================================================================
|
|
// ACCORDION FUNCTIONALITY
|
|
// ============================================================================
|
|
|
|
// 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');
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// RESEARCH INQUIRY MODAL FUNCTIONALITY
|
|
// ============================================================================
|
|
|
|
const modal = document.getElementById('research-inquiry-modal');
|
|
const openButton = document.getElementById('research-inquiry-button');
|
|
const closeButton = document.getElementById('close-modal');
|
|
const cancelButton = document.getElementById('cancel-modal');
|
|
const form = document.getElementById('research-inquiry-form');
|
|
const successMessage = document.getElementById('success-message');
|
|
const closeSuccessButton = document.getElementById('close-success');
|
|
|
|
// Open modal
|
|
if (openButton) {
|
|
openButton.addEventListener('click', function() {
|
|
modal.classList.remove('hidden');
|
|
document.body.style.overflow = 'hidden'; // Prevent background scrolling
|
|
});
|
|
}
|
|
|
|
// Close modal function
|
|
function closeModal() {
|
|
modal.classList.add('hidden');
|
|
document.body.style.overflow = ''; // Restore scrolling
|
|
form.classList.remove('hidden');
|
|
successMessage.classList.add('hidden');
|
|
form.reset();
|
|
}
|
|
|
|
// Close button
|
|
if (closeButton) {
|
|
closeButton.addEventListener('click', closeModal);
|
|
}
|
|
|
|
// Cancel button
|
|
if (cancelButton) {
|
|
cancelButton.addEventListener('click', closeModal);
|
|
}
|
|
|
|
// Close success button
|
|
if (closeSuccessButton) {
|
|
closeSuccessButton.addEventListener('click', closeModal);
|
|
}
|
|
|
|
// Close on background click
|
|
if (modal) {
|
|
modal.addEventListener('click', function(e) {
|
|
if (e.target === modal) {
|
|
closeModal();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Close on Escape key
|
|
document.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape' && !modal.classList.contains('hidden')) {
|
|
closeModal();
|
|
}
|
|
});
|
|
|
|
// Form submission
|
|
if (form) {
|
|
form.addEventListener('submit', async function(e) {
|
|
e.preventDefault();
|
|
|
|
// Get form data
|
|
const formData = new FormData(form);
|
|
|
|
// Get all selected needs
|
|
const needs = [];
|
|
document.querySelectorAll('input[name="needs"]:checked').forEach(checkbox => {
|
|
needs.push(checkbox.value);
|
|
});
|
|
|
|
// Build submission object
|
|
const data = {
|
|
researchQuestion: formData.get('research-question'),
|
|
methodology: formData.get('methodology'),
|
|
context: formData.get('context'),
|
|
needs: needs,
|
|
otherNeeds: formData.get('other-needs'),
|
|
institution: formData.get('institution'),
|
|
name: formData.get('name'),
|
|
email: formData.get('email'),
|
|
timeline: formData.get('timeline'),
|
|
submittedAt: new Date().toISOString()
|
|
};
|
|
|
|
try {
|
|
// Send to server (API endpoint to be implemented)
|
|
const response = await fetch('/api/research-inquiry', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(data)
|
|
});
|
|
|
|
if (response.ok) {
|
|
// Show success message
|
|
form.classList.add('hidden');
|
|
successMessage.classList.remove('hidden');
|
|
} else {
|
|
// Handle error
|
|
alert('An error occurred submitting your inquiry. Please try again or email contact@agenticgovernance.digital directly.');
|
|
}
|
|
} catch (error) {
|
|
console.error('Submission error:', error);
|
|
alert('An error occurred submitting your inquiry. Please try again or email contact@agenticgovernance.digital directly.');
|
|
}
|
|
});
|
|
}
|
|
});
|