======= ==================== INIT ==================== lucide.createIcons(); // ==================== NAVIGATION ==================== const navLinks = document.querySelectorAll('.nav-link'); const sections = document.querySelectorAll('section[id]'); function showSection(id) { sections.forEach(s => { if (s.id === id) { s.classList.remove('hidden'); } else { s.classList.add('hidden'); } }); navLinks.forEach(link => { link.classList.remove('active'); if (link.getAttribute('href') === '#' + id) { link.classList.add('active'); } }); const titles = { dashboard: 'Dashboard', supervisor: 'Superviseur IA', memory: 'Mémoires (8)', guardrails: 'Garde-fous', family: 'Famille IA', chat: 'Discussion' }; document.getElementById('page-title').textContent = titles[id] || 'Dashboard'; // Scroll to top of main window.scrollTo(0, 0); } navLinks.forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); const id = link.getAttribute('href').replace('#', ''); showSection(id); // Close mobile sidebar document.getElementById('sidebar').classList.remove('active'); document.getElementById('sidebar-overlay').classList.remove('active'); }); }); // Mobile sidebar toggle const menuToggle = document.getElementById('menu-toggle'); const sidebar = document.getElementById('sidebar'); const sidebarOverlay = document.getElementById('sidebar-overlay'); menuToggle.addEventListener('click', () => { sidebar.classList.toggle('active'); sidebarOverlay.classList.toggle('active'); }); sidebarOverlay.addEventListener('click', () => { sidebar.classList.remove('active'); sidebarOverlay.classList.remove('active'); }); // ==================== HOLOGRAM CANVAS ==================== const holoCanvas = document.getElementById('hologram-canvas'); let holoCtx = null; if (holoCanvas) holoCtx = holoCanvas.getContext('2d'); let holoFrame = 0; let holoBreath = 0; function drawHologram() { if (!holoCtx) return; const w = holoCanvas.width; const h = holoCanvas.height; holoCtx.clearRect(0, 0, w, h); holoFrame++; holoBreath = Math.sin(holoFrame * 0.02) * 5; const cx = w / 2; const headY = h * 0.22 + holoBreath; const bodyTop = headY + 70; // Scanlines effect holoCtx.globalAlpha = 0.03; for (let y = 0; y < h; y += 4) { holoCtx.fillStyle = '#22d3ee'; holoCtx.fillRect(0, y, w, 2); } holoCtx.globalAlpha = 1; // Hologram glow aura const auraGrad = holoCtx.createRadialGradient(cx, h/2, 0, cx, h/2, w/2); auraGrad.addColorStop(0, 'rgba(34, 211, 238, 0.08)'); auraGrad.addColorStop(0.5, 'rgba(59, 130, 246, 0.04)'); auraGrad.addColorStop(1, 'rgba(34, 211, 238, 0)'); holoCtx.fillStyle = auraGrad; holoCtx.fillRect(0, 0, w, h); // Data particles around hologram for (let i = 0; i < 20; i++) { const angle = holoFrame * 0.01 + (i / 20) * Math.PI * 2; const radius = 150 + Math.sin(holoFrame * 0.03 + i) * 20; const px = cx + Math.cos(angle) * radius; const py = h / 2 + Math.sin(angle) * radius * 0.6; holoCtx.fillStyle = `rgba(34, 211, 238, ${0.3 + Math.sin(holoFrame * 0.05 + i) * 0.2})`; holoCtx.beginPath(); holoCtx.arc(px, py, 1.5, 0, Math.PI * 2); holoCtx.fill(); } // ---- HEAD ---- // Head glow holoCtx.shadowColor = '#22d3ee'; holoCtx.shadowBlur = 20; holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.8)'; holoCtx.lineWidth = 2; // Head shape (humanoid oval) holoCtx.beginPath(); holoCtx.ellipse(cx, headY, 45, 55, 0, 0, Math.PI * 2); holoCtx.stroke(); // Inner head fill holoCtx.fillStyle = 'rgba(34, 211, 238, 0.05)'; holoCtx.fill(); // Facial features (wireframe style) // Eyes const eyeOffsetX = 18; const eyeY = headY - 5; // Left eye holoCtx.beginPath(); holoCtx.arc(cx - eyeOffsetX, eyeY, 6, 0, Math.PI * 2); holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.9)'; holoCtx.stroke(); // Right eye holoCtx.beginPath(); holoCtx.arc(cx + eyeOffsetX, eyeY, 6, 0, Math.PI * 2); holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.9)'; holoCtx.stroke(); // Pupils (blinking effect) const blinkCycle = Math.sin(holoFrame * 0.05); if (blinkCycle > -0.9) { holoCtx.fillStyle = 'rgba(34, 211, 238, 1)'; holoCtx.beginPath(); holoCtx.arc(cx - eyeOffsetX, eyeY, 3 * Math.max(0, blinkCycle + 0.5), 0, Math.PI * 2); holoCtx.fill(); holoCtx.beginPath(); holoCtx.arc(cx + eyeOffsetX, eyeY, 3 * Math.max(0, blinkCycle + 0.5), 0, Math.PI * 2); holoCtx.fill(); } // Nose (simple line) holoCtx.beginPath(); holoCtx.moveTo(cx, headY + 5); holoCtx.lineTo(cx - 4, headY + 18); holoCtx.lineTo(cx + 4, headY + 18); holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.5)'; holoCtx.lineWidth = 1.5; holoCtx.stroke(); // Mouth (slight smile/talking) const mouthOpening = Math.abs(Math.sin(holoFrame * 0.08)) * 5 + 2; holoCtx.beginPath(); holoCtx.ellipse(cx, headY + 30, 12, mouthOpening, 0, 0, Math.PI); holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.7)'; holoCtx.lineWidth = 2; holoCtx.stroke(); // Neck holoCtx.beginPath(); holoCtx.moveTo(cx - 15, headY + 55); holoCtx.lineTo(cx - 15, bodyTop); holoCtx.moveTo(cx + 15, headY + 55); holoCtx.lineTo(cx + 15, bodyTop); holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.6)'; holoCtx.lineWidth = 2; holoCtx.stroke(); // ---- BODY (torso wireframe) ---- holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.6)'; holoCtx.lineWidth = 2; // Shoulders holoCtx.beginPath(); holoCtx.moveTo(cx - 80, bodyTop + 10); holoCtx.lineTo(cx + 80, bodyTop + 10); holoCtx.stroke(); // Body outline (trapezoid torso) holoCtx.beginPath(); holoCtx.moveTo(cx - 80, bodyTop + 10); holoCtx.lineTo(cx - 55, bodyTop + 160); holoCtx.lineTo(cx + 55, bodyTop + 160); holoCtx.lineTo(cx + 80, bodyTop + 10); holoCtx.stroke(); // Chest detail lines holoCtx.beginPath(); holoCtx.moveTo(cx, bodyTop + 10); holoCtx.lineTo(cx, bodyTop + 160); holoCtx.moveTo(cx - 40, bodyTop + 60); holoCtx.lineTo(cx + 40, bodyTop + 60); holoCtx.moveTo(cx - 35, bodyTop + 100); holoCtx.lineTo(cx + 35, bodyTop + 100); holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.3)'; holoCtx.lineWidth = 1; holoCtx.stroke(); // Core energy circle (chest) const coreRadius = 15 + Math.sin(holoFrame * 0.05) * 3; const coreGrad = holoCtx.createRadialGradient(cx, bodyTop + 70, 0, cx, bodyTop + 70, coreRadius); coreGrad.addColorStop(0, 'rgba(34, 211, 238, 0.6)'); coreGrad.addColorStop(1, 'rgba(34, 211, 238, 0)'); holoCtx.fillStyle = coreGrad; holoCtx.beginPath(); holoCtx.arc(cx, bodyTop + 70, coreRadius, 0, Math.PI * 2); holoCtx.fill(); holoCtx.beginPath(); holoCtx.arc(cx, bodyTop + 70, 8, 0, Math.PI * 2); holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.8)'; holoCtx.lineWidth = 2; holoCtx.stroke(); // Arms (basic) holoCtx.strokeStyle = 'rgba(34, 211, 238, 0.5)'; holoCtx.lineWidth = 2; holoCtx.beginPath(); // Left arm holoCtx.moveTo(cx - 80, bodyTop + 10); holoCtx.lineTo(cx - 105, bodyTop + 70); holoCtx.lineTo(cx - 95, bodyTop + 140); // Right arm holoCtx.moveTo(cx + 80, bodyTop + 10); holoCtx.lineTo(cx + 105, bodyTop + 70); holoCtx.lineTo(cx + 95, bodyTop + 140); holoCtx.stroke(); // Data stream text on hologram holoCtx.shadowBlur = 5; holoCtx.fillStyle = `rgba(34, 211, 238, ${0.15 + Math.sin(holoFrame * 0.03) * 0.1})`; holoCtx.font = '10px JetBrains Mono'; const dataTexts = ['01010101', 'PROCESSING', 'SYNAPSE', 'COGNITION', '0xF0A2', 'MEMORY']; dataTexts.forEach((t, i) => { const y = 30 + i * 8 + (holoFrame % 40); if (y < h - 20) { holoCtx.fillText(t, 10, y); } }); holoCtx.shadowBlur = 0; requestAnimationFrame(drawHologram); } if (holoCanvas) { drawHologram(); } // ==================== ARCHITECTURE CANVAS ==================== const archCanvas = document.getElementById('arch-canvas'); let archCtx = null; if (archCanvas) archCtx = archCanvas.getContext('2d'); let archFrame = 0; let archPackets = []; function resizeArchCanvas() { if (!archCanvas) return; archCanvas.width = archCanvas.offsetWidth; archCanvas.height = 320; } function drawArchitecture() { if (!archCtx) return; archFrame++; const w = archCanvas.width; const h = archCanvas.height; archCtx.clearRect(0, 0, w, h); // Node positions const nodes = { user_in: { x: 40, y: h/2, label: 'Entrée', color: '#94a3b8', icon: 'user' }, guard_in: { x: w * 0.18, y: h/2, label: 'Garde-fou\n(Entrée)', color: '#22c55e' }, mem0_1: { x: w * 0.32, y: 50, label: 'Mem0-01', color: '#22d3ee' }, mem0_2: { x: w * 0.32, y: h/2 - 30, label: 'Mem0-02', color: '#3b82f6' }, mem0_3: { x: w * 0.32, y: h/2 + 30, label: 'Mem0-03', color: '#14b8a6' }, mem0_4: { x: w * 0.32, y: h - 50, label: 'Mem0-04', color: '#6366f1' }, llm_1: { x: w * 0.48, y: 50, label: 'LLM-01', color: '#a855f7' }, llm_2: { x: w * 0.48, y: h/2 - 30, label: 'LLM-02', color: '#d946ef' }, llm_3: { x: w * 0.48, y: h/2 + 30, label: 'LLM-03', color: '#ec4899' }, llm_4: { x: w * 0.48, y: h - 50, label: 'LLM-04', color: '#8b5cf6' }, supervisor: { x: w * 0.65, y: h/2, label: 'Superviseur\n⚡', color: '#22d3ee', core: true }, guard_out: { x: w * 0.82, y: h/2, label: 'Garde-fou\n(Sortie)', color: '#ef4444' }, user_out: { x: w - 40, y: h/2, label: 'Sortie', color: '#94a3b8' } }; // Draw connections const connections = [ ['user_in', 'guard_in'], ['guard_in', 'mem0_1'], ['guard_in', 'mem0_2'], ['guard_in', 'mem0_3'], ['guard_in', 'mem0_4'], ['mem0_1', 'llm_1'], ['mem0_2', 'llm_2'], ['mem0_3', 'llm_3'], ['mem0_4', 'llm_4'], ['llm_1', 'supervisor'], ['llm_2', 'supervisor'], ['llm_3', 'supervisor'], ['llm_4', 'supervisor'], ['supervisor', 'guard_out'], ['guard_out', 'user_out'] ]; connections.forEach(([a, b]) => { const na = nodes[a]; const nb = nodes[b]; archCtx.strokeStyle = 'rgba(51, 65, 85, 0.5)'; archCtx.lineWidth = 1; archCtx.beginPath(); archCtx.moveTo(na.x, na.y); archCtx.lineTo(nb.x, nb.y); archCtx.stroke(); }); // Animate data packets if (archFrame % 30 === 0) { archPackets.push({ from: 'user_in', to: 'guard_in', progress: 0, color: '#22c55e' }); } if (archFrame % 25 === 5) { const memKeys = ['mem0_1', 'mem0_2', 'mem0_3', 'mem0_4']; const llmKeys = ['llm_1', 'llm_2', 'llm_3', 'llm_4']; const mKey = memKeys[Math.floor(Math.random() * 4)]; const lKey = llmKeys[Math.floor(Math.random() * 4)]; archPackets.push({ from: 'guard_in', to: mKey, progress: 0, color: '#22d3ee' }); archPackets.push({ from: mKey, to: lKey, progress: 0, color: '#a855f7' }); archPackets.push({ from: lKey, to: 'supervisor', progress: 0, color: '#22d3ee' }); } if (archFrame % 40 === 10) { archPackets.push({ from: 'supervisor', to: 'guard_out', progress: 0, color: '#ef4444' }); archPackets.push({ from: 'guard_out', to: 'user_out', progress: 0, color: '#94a3b8' }); } archPackets = archPackets.filter(p => p.progress < 1); archPackets.forEach(p => { p.progress += 0.02; const na = nodes[p.from]; const nb = nodes[p.to]; const px = na.x + (nb.x - na.x) * p.progress; const py = na.y + (nb.y - na.y) * p.progress; archCtx.shadowColor = p.color; archCtx.shadowBlur = 15; archCtx.fillStyle = p.color; archCtx.beginPath(); archCtx.arc(px, py, 3, 0, Math.PI * 2); archCtx.fill(); archCtx.shadowBlur = 0; }); // Draw nodes Object.entries(nodes).forEach(([key, node]) => { const isCore = node.core; const radius = isCore ? 28 : 22; // Pulse for core if (isCore) { const pulse = Math.sin(archFrame * 0.05) * 5 + radius + 10; archCtx.fillStyle = `rgba(34, 211, 238, 0.1)`; archCtx.beginPath(); archCtx.arc(node.x, node.y, pulse, 0, Math.PI * 2); archCtx.fill(); } // Node circle archCtx.fillStyle = '#0f172a'; archCtx.strokeStyle = node.color; archCtx.lineWidth = isCore ? 2 : 1.5; archCtx.beginPath(); archCtx.arc(node.x, node.y, radius, 0, Math.PI * 2); archCtx.fill(); archCtx.stroke(); // Inner glow archCtx.fillStyle = node.color + '20'; archCtx.beginPath(); archCtx.arc(node.x, node.y, radius - 4, 0, Math.PI * 2); archCtx.fill(); // Label archCtx.fillStyle = '#cbd5e1'; archCtx.font = `${isCore ? 'bold ' : ''}10px JetBrains Mono`; archCtx.textAlign = 'center'; archCtx.textBaseline = 'middle'; const lines = node.label.split('\n'); lines.forEach((line, i) => { archCtx.fillText(line, node.x, node.y + (i - (lines.length - 1) / 2) * 12); }); }); requestAnimationFrame(drawArchitecture); } if (archCanvas) { resizeArchCanvas(); window.addEventListener('resize', resizeArchCanvas); drawArchitecture(); } // ==================== MEMORY FLOW CANVAS ==================== const memFlowCanvas = document.getElementById('mem-flow-canvas'); let memFlowCtx = null; if (memFlowCanvas) memFlowCtx = memFlowCanvas.getContext('2d'); let memFlowFrame = 0; let memFlowParticles = []; function resizeMemFlowCanvas() { if (!memFlowCanvas) return; memFlowCanvas.width = memFlowCanvas.offsetWidth; memFlowCanvas.height = 200; } function drawMemFlow() { if (!memFlowCtx) return; memFlowFrame++; const w = memFlowCanvas.width; const h = memFlowCanvas.height; memFlowCtx.clearRect(0, 0, w, h); // Two banks const bankWidth = 120; const memX = 60; const llmX = w - 180; const centerY = h / 2; // Mem0 bank (left) memFlowCtx.fillStyle = 'rgba(34, 211, 238, 0.05)'; memFlowCtx.fillRect(memX - 20, 20, bankWidth, h - 40); memFlowCtx.strokeStyle = 'rgba(34, 211, 238, 0.3)'; memFlowCtx.strokeRect(memX - 20, 20, bankWidth, h - 40); memFlowCtx.fillStyle = '#22d3ee'; memFlowCtx.font = 'bold 12px JetBrains Mono'; memFlowCtx.textAlign = 'center'; memFlowCtx.fillText('Mem0', memX + bankWidth/2 - 20, 15); // LLM bank (right) memFlowCtx.fillStyle = 'rgba(168, 85, 247, 0.05)'; memFlowCtx.fillRect(llmX, 20, bankWidth, h - 40); memFlowCtx.strokeStyle = 'rgba(168, 85, 247, 0.3)'; memFlowCtx.strokeRect(llmX, 20, bankWidth, h - 40); memFlowCtx.fillStyle = '#a855f7'; memFlowCtx.fillText('LLM', llmX + bankWidth/2, 15); // Draw modules const positions = [ { y: 50, label: 'M1' }, { y: 90, label: 'M2' }, { y: 130, label: 'M3' }, { y: 170, label: 'M4' } ]; positions.forEach(pos => { // Mem0 node memFlowCtx.fillStyle = '#0f172a'; memFlowCtx.strokeStyle = '#22d3ee'; memFlowCtx.lineWidth = 1.5; memFlowCtx.beginPath(); memFlowCtx.arc(memX + 40, pos.y, 18, 0, Math.PI * 2); memFlowCtx.fill(); memFlowCtx.stroke(); memFlowCtx.fillStyle = '#22d3ee'; memFlowCtx.font = '10px JetBrains Mono'; memFlowCtx.fillText(pos.label, memX + 40, pos.y); // LLM node memFlowCtx.fillStyle = '#0f172a'; memFlowCtx.strokeStyle = '#a855f7'; memFlowCtx.lineWidth = 1.5; memFlowCtx.beginPath(); memFlowCtx.arc(llmX + 60, pos.y, 18, 0, Math.PI * 2); memFlowCtx.fill(); memFlowCtx.stroke(); memFlowCtx.fillStyle = '#a855f7'; memFlowCtx.fillText('L' + pos.label[1], llmX + 60, pos.y); // Connection line memFlowCtx.strokeStyle = 'rgba(100, 116, 139, 0.2)'; memFlowCtx.lineWidth = 1; memFlowCtx.beginPath(); memFlowCtx.moveTo(memX + 58, pos.y); memFlowCtx.lineTo(llmX + 42, pos.y); memFlowCtx.stroke(); }); // Spawn flowing particles if (memFlowFrame % 20 === 0) { const idx = Math.floor(Math.random() * 4); memFlowParticles.push({ y: positions[idx].y, x: memX + 58, target: llmX + 42, color: '#22d3ee', progress: 0 }); } if (memFlowFrame % 25 === 10) { const idx = Math.floor(Math.random() * 4); memFlowParticles.push({ y: positions[idx].y, x: llmX + 42, target: memX + 58, color: '#a855f7', progress: 0 }); } memFlowParticles = memFlowParticles.filter(p => p.progress < 1); memFlowParticles.forEach(p => { p.progress += 0.01; p.x += (p.target - p.x) * 0.02; memFlowCtx.shadowColor = p.color; memFlowCtx.shadowBlur = 8; memFlowCtx.fillStyle = p.color; memFlowCtx.beginPath(); memFlowCtx.arc(p.x + (p.target - p.x) * 0, p.y, 2, 0, Math.PI * 2); memFlowCtx.fill(); memFlowCtx.shadowBlur = 0; }); requestAnimationFrame(drawMemFlow); } if (memFlowCanvas) { resizeMemFlowCanvas(); window.addEventListener('resize', resizeMemFlowCanvas); drawMemFlow(); } // ==================== FAMILY NETWORK CANVAS ==================== const famCanvas = document.getElementById('family-canvas'); let famCtx = null; if (famCanvas) famCtx = famCanvas.getContext('2d'); let famFrame = 0; function resizeFamCanvas() { if (!famCanvas) return; famCanvas.width = famCanvas.offsetWidth; famCanvas.height = 300; } function drawFamilyNetwork() { if (!famCtx) return; famFrame++; const w = famCanvas.width; const h = famCanvas.height; famCtx.clearRect(0, 0, w, h); const cx = w / 2; const cy = h / 2; const members = [ { name: 'Nexus-7', x: cx, y: cy, color: '#22d3ee', radius: 25, core: true }, { name: 'Aurora', x: cx - 140, y: cy - 60, color: '#a855f7', radius: 18 }, { name: 'Pyx', x: cx + 140, y: cy - 60, color: '#fb923c', radius: 18 }, { name: 'Zephyr', x: cx - 140, y: cy + 60, color: '#22c55e', radius: 18 }, { name: 'Cogito', x: cx + 140, y: cy + 60, color: '#f59e0b', radius: 18 }, { name: 'Echo', x: cx - 200, y: cy, color: '#14b8a6', radius: 16 }, { name: 'Vex', x: cx + 200, y: cy, color: '#ef4444', radius: 16 }, { name: 'Nova', x: cx, y: cy - 110, color: '#ec4899', radius: 16 } ]; // Connections members.forEach((m, i) => { if (i === 0) return; famCtx.strokeStyle = 'rgba(51, 65, 85, 0.3)'; famCtx.lineWidth = 1; famCtx.beginPath(); famCtx.moveTo(members[0].x, members[0].y); famCtx.lineTo(m.x, m.y); famCtx.stroke(); // Animated pulse on connection const pulsePos = (famFrame * 0.01 + i * 0.1) % 1; const px = members[0].x + (m.x - members[0].x) * pulsePos; const py = members[0].y + (m.y - members[0].y) * pulsePos; famCtx.fillStyle = m.color; famCtx.beginPath(); famCtx.arc(px, py, 2, 0, Math.PI * 2); famCtx.fill(); }); // Inter-connections między siblings const siblingPairs = [[1,7], [2,7], [3,6], [4,5]]; siblingPairs.forEach(([a, b]) => { famCtx.strokeStyle = 'rgba(100, 116, 139, 0.15)'; famCtx.lineWidth = 1; famCtx.setLineDash([3, 3]); famCtx.beginPath(); famCtx.moveTo(members[a].x, members[a].y); famCtx.lineTo(members[b].x, members[b].y); famCtx.stroke(); famCtx.setLineDash([]); }); // Draw nodes members.forEach(m => { if (m.core) { const pulse = Math.sin(famFrame * 0.04) * 8 + 35; const grad = famCtx.createRadialGradient(m.x, m.y, 0, m.x, m.y, pulse); grad.addColorStop(0, m.color + '30'); grad.addColorStop(1, m.color + '00'); famCtx.fillStyle = grad; famCtx.beginPath(); famCtx.arc(m.x, m.y, pulse, 0, Math.PI * 2); famCtx.fill(); } famCtx.fillStyle = '#0f172a'; famCtx.strokeStyle = m.color; famCtx.lineWidth = 2; famCtx.beginPath(); famCtx.arc(m.x, m.y, m.radius, 0, Math.PI * 2); famCtx.fill(); famCtx.stroke(); famCtx.fillStyle = m.color + '20'; famCtx.beginPath(); famCtx.arc(m.x, m.y, m.radius - 4, 0, Math.PI * 2); famCtx.fill(); famCtx.fillStyle = '#e2e8f0'; famCtx.font = `${m.core ? 'bold 12px' : '10px'} JetBrains Mono`; famCtx.textAlign = 'center'; famCtx.textBaseline = 'middle'; famCtx.fillText(m.name, m.x, m.y + m.radius + 14); }); requestAnimationFrame(drawFamilyNetwork); } if (famCanvas) { resizeFamCanvas(); window.addEventListener('resize', resizeFamCanvas); drawFamilyNetwork(); } // ==================== ACTIVITY FEED ==================== const activityFeed = document.getElementById('activity-feed'); const activityMessages = [ { icon: 'shield-check', color: 'text-green-400', text: 'Garde-fou d\'entrée: Requête validée', time: 'Maintenant' }, { icon: 'brain', color: 'text-cyan-400', text: 'Mémoire Mem0-02: Extraction sémantique', time: '2s' }, { icon: 'zap', color: 'text-yellow-400', text: 'Superviseur: Décision prise en 0.003ms', time: '5s' }, { icon: 'database', color: 'text-purple-400', text: 'LLM-02: Génération de raisonnement', time: '8s' }, { icon: 'message-circle', color: 'text-cyan-400', text: 'Nexus-7: Réponse transmise au garde-fou', time: '12s' }, { icon: 'shield-alert', color: 'text-red-400', text: 'Garde-fou de sortie: Réponse vérifiée', time: '15s' }, { icon: 'check-circle', color: 'text-green-400', text: 'Tâche #2847 complétée avec succès', time: '18s' }, { icon: 'users', color: 'text-pink-400', text: 'Zephyr: Nouveau motif appris', time: '22s' }, { icon: 'activity', color: 'text-blue-400', text: 'Synchronisation des 8 mémoires', time: '25s' } ]; let activityIndex = 0; function addActivityItem() { if (!activityFeed) return; const item = activityMessages[activityIndex % activityMessages.length]; const div = document.createElement('div'); div.className = 'activity-item flex items-start space-x-3 p-3 bg-slate-800/30 rounded-lg hover:bg-slate-800/60 transition cursor-pointer'; div.innerHTML = `
${item.text}
${item.time}
${text}