tractatus/public/js/demos/tractatus-demo.js
TheFlow 2e6618b7ba feat: fix CSP violations & implement three audience paths
CSP Compliance (complete):
- Install Tailwind CSS v3 locally (24KB build)
- Replace CDN with /css/tailwind.css in all HTML files
- Extract all inline scripts to external JS files
- Created 6 external JS files for demos & docs
- All pages now comply with script-src 'self'

Three Audience Paths (complete):
- Created /researcher.html (academic/theoretical)
- Created /implementer.html (practical integration)
- Created /advocate.html (mission/values/community)
- Updated homepage links to audience pages
- Each path has dedicated nav, hero, resources, CTAs

Files Modified (20):
- 7 HTML files (CSP compliance)
- 3 audience landing pages (new)
- 6 external JS files (extracted)
- package.json (Tailwind v3)
- tailwind.config.js (new)
- Built CSS (24KB minified)

All resources CSP-compliant, all pages tested 200 OK

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-07 12:21:00 +13:00

110 lines
4.9 KiB
JavaScript

// Demo tab switching
function showDemo(demoId) {
document.querySelectorAll('.demo-content').forEach(el => el.classList.add('hidden'));
document.querySelectorAll('.demo-tab').forEach(el => {
el.classList.remove('border-blue-500', 'text-blue-600');
el.classList.add('border-transparent', 'text-gray-500');
});
document.getElementById('demo-' + demoId).classList.remove('hidden');
document.getElementById('tab-' + demoId).classList.remove('border-transparent', 'text-gray-500');
document.getElementById('tab-' + demoId).classList.add('border-blue-500', 'text-blue-600');
}
// Classification API call
async function classifyInstruction() {
const text = document.getElementById('classify-input').value;
if (!text) return;
try {
const response = await fetch('/api/governance', { method: 'GET' });
// Simulate classification (in production, this would call the actual API with auth)
const result = {
quadrant: text.toLowerCase().includes('always') || text.toLowerCase().includes('never') ? 'STRATEGIC' :
text.toLowerCase().includes('port') || text.toLowerCase().includes('check') ? 'TACTICAL' :
text.toLowerCase().includes('code') ? 'SYSTEM' : 'OPERATIONAL',
persistence: text.toLowerCase().includes('always') || text.toLowerCase().includes('never') ? 'HIGH' :
text.match(/\d{4,}/) ? 'HIGH' : 'MEDIUM',
verification: 'MANDATORY',
explicitness: text.match(/\d{4,}/) ? '0.9' : '0.6',
humanOversight: 'VALUES_STEWARDSHIP'
};
document.getElementById('result-quadrant').textContent = result.quadrant;
document.getElementById('result-quadrant-desc').textContent =
result.quadrant === 'STRATEGIC' ? 'Long-term values & mission' :
result.quadrant === 'TACTICAL' ? 'Immediate implementation' :
result.quadrant === 'SYSTEM' ? 'Technical infrastructure' : 'Process & policy';
document.getElementById('result-persistence').textContent = result.persistence;
document.getElementById('result-verification').textContent = result.verification;
document.getElementById('result-explicitness').textContent = result.explicitness;
document.getElementById('result-oversight').textContent = result.humanOversight;
document.getElementById('classify-result').classList.remove('hidden');
document.getElementById('classify-result').classList.add('fade-in');
} catch (error) {
console.error('Classification error:', error);
}
}
// Pressure calculation
function updatePressure() {
const tokens = parseInt(document.getElementById('token-slider').value);
const messages = parseInt(document.getElementById('messages-slider').value);
const errors = parseInt(document.getElementById('errors-slider').value);
document.getElementById('token-value').textContent = tokens.toLocaleString();
document.getElementById('messages-value').textContent = messages;
document.getElementById('errors-value').textContent = errors;
// Calculate pressure (simplified)
const tokenPressure = (tokens / 200000) * 0.35;
const messagePressure = Math.min(messages / 100, 1) * 0.25;
const errorPressure = Math.min(errors / 3, 1) * 0.4;
const totalPressure = tokenPressure + messagePressure + errorPressure;
const percentage = Math.round(totalPressure * 100);
document.getElementById('pressure-percentage').textContent = percentage + '%';
document.getElementById('pressure-bar').style.width = percentage + '%';
let level, badgeClass, barClass, message;
if (totalPressure < 0.3) {
level = 'NORMAL';
badgeClass = 'bg-green-100 text-green-800';
barClass = 'bg-green-500';
message = 'Operating normally. All systems green.';
} else if (totalPressure < 0.5) {
level = 'ELEVATED';
badgeClass = 'bg-yellow-100 text-yellow-800';
barClass = 'bg-yellow-500';
message = 'Elevated pressure detected. Increased verification recommended.';
} else if (totalPressure < 0.7) {
level = 'HIGH';
badgeClass = 'bg-orange-100 text-orange-800';
barClass = 'bg-orange-500';
message = 'High pressure. Mandatory verification required for all actions.';
} else if (totalPressure < 0.85) {
level = 'CRITICAL';
badgeClass = 'bg-red-100 text-red-800';
barClass = 'bg-red-500';
message = 'Critical pressure! Recommend context refresh or session restart.';
} else {
level = 'DANGEROUS';
badgeClass = 'bg-red-200 text-red-900';
barClass = 'bg-red-700';
message = 'DANGEROUS CONDITIONS. Human intervention required. Action execution blocked.';
}
const badge = document.getElementById('pressure-badge');
badge.textContent = level;
badge.className = 'px-3 py-1 rounded-full text-sm font-medium ' + badgeClass;
const bar = document.getElementById('pressure-bar');
bar.className = 'h-3 rounded-full transition-all duration-300 ' + barClass;
document.getElementById('pressure-recommendations').textContent = message;
}
// Initialize
updatePressure();