tractatus/public/js/researcher-page.js
TheFlow d1596aa3f6 feat(researcher): radical overhaul of limitations section and research collaboration
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>
2025-10-29 00:48:08 +13:00

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