Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
17 pages injectees via inject-d60-direct.py: - acquired-dashboard brain-center-tenant claude-monitor - command-center contacts-segmentation-dashboard crm-dashboard-live - crons-monitor dashboards-index database-dashboard-live - dg-command-center director-center e2e-dashboard em-dashboard - ethica-dashboard-live ethica-monitor infra-dashboard-live - lean6sigma-dashboard Total session cumul: 92 pages UX doctrine 60 (75 + 17) Tags Opus: 30 Doctrines vault: 27 (146-182) ZERO regression. Train multi-Claude sync: - autre Claude opus_disaster_recovery (187 intents) - autre Claude opus_cyber_profile_manager - NR 153/153 invariant
366 lines
19 KiB
HTML
366 lines
19 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr"><head><meta charset="UTF-8"><title>📊 Dashboards Index · WEVAL Consolidated</title>
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
<style>
|
|
*{margin:0;padding:0;box-sizing:border-box;font-family:-apple-system,'Segoe UI',sans-serif}
|
|
body{background:linear-gradient(135deg,#0b0d15 0%,#1a1f3a 100%);color:#e2e8f0;min-height:100vh;padding:20px}
|
|
.container{max-width:1400px;margin:0 auto}
|
|
h1{font-family:'Orbitron',sans-serif;font-weight:900;
|
|
background:linear-gradient(135deg,#06b6d4,#8b5cf6,#ec4899);
|
|
-webkit-background-clip:text;-webkit-text-fill-color:transparent;
|
|
font-size:2.2rem;margin-bottom:6px;letter-spacing:1.5px;text-transform:uppercase}
|
|
.subtitle{color:#94a3b8;margin-bottom:20px;font-size:0.9rem}
|
|
.hero{background:linear-gradient(135deg,rgba(6,182,212,0.08),rgba(139,92,246,0.08),rgba(236,72,153,0.06));
|
|
border:1px solid rgba(6,182,212,0.25);border-radius:16px;padding:22px;margin-bottom:24px;
|
|
backdrop-filter:blur(16px);position:relative;overflow:hidden}
|
|
.hero::before{content:'';position:absolute;top:-50%;right:-50%;width:100%;height:100%;
|
|
background:radial-gradient(circle,rgba(6,182,212,0.08) 0%,transparent 70%);pointer-events:none}
|
|
.hero-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:14px;position:relative}
|
|
.stat{text-align:center;padding:8px 4px}
|
|
.stat-val{font-family:'Orbitron',sans-serif;font-size:2rem;font-weight:900;line-height:1}
|
|
.stat-val.success{color:#22c55e}
|
|
.stat-val.warn{color:#f59e0b}
|
|
.stat-val.info{color:#06b6d4}
|
|
.stat-val.purple{color:#a855f7}
|
|
.stat-lbl{font-size:0.65rem;color:#64748b;text-transform:uppercase;letter-spacing:1.5px;margin-top:4px}
|
|
|
|
.filters{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:20px}
|
|
.filter{padding:6px 14px;border-radius:8px;font-size:0.78rem;font-weight:700;cursor:pointer;
|
|
background:rgba(30,41,59,0.8);color:#94a3b8;border:1px solid rgba(100,116,139,0.2);
|
|
transition:all 0.15s;text-transform:uppercase;letter-spacing:0.5px}
|
|
.filter.active{background:linear-gradient(135deg,#06b6d4,#8b5cf6);color:#fff;border-color:transparent}
|
|
.filter:hover{transform:translateY(-1px)}
|
|
|
|
.section-title{color:#c084fc;font-size:0.85rem;font-weight:800;text-transform:uppercase;
|
|
letter-spacing:2px;margin:22px 0 10px;padding-left:10px;border-left:3px solid #a855f7}
|
|
|
|
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;margin-bottom:20px}
|
|
.card{background:rgba(15,23,42,0.85);border:1px solid rgba(100,116,139,0.15);border-radius:12px;
|
|
padding:14px 16px;transition:all 0.2s;display:block;text-decoration:none;color:inherit;
|
|
position:relative;overflow:hidden}
|
|
.card:hover{transform:translateY(-2px);border-color:rgba(6,182,212,0.4);
|
|
box-shadow:0 8px 24px rgba(6,182,212,0.12)}
|
|
.card::after{content:'→';position:absolute;top:14px;right:14px;color:#64748b;font-size:1.2rem;
|
|
transition:all 0.2s}
|
|
.card:hover::after{color:#06b6d4;transform:translateX(3px)}
|
|
.card-header{display:flex;align-items:center;gap:10px;margin-bottom:6px}
|
|
.card-icon{font-size:1.4rem}
|
|
.card-title{font-weight:800;font-size:0.95rem;color:#e2e8f0}
|
|
.card-desc{color:#94a3b8;font-size:0.78rem;line-height:1.4;margin-bottom:8px}
|
|
.card-meta{display:flex;gap:8px;font-size:0.7rem}
|
|
.badge{padding:2px 8px;border-radius:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.5px}
|
|
.badge.new{background:rgba(34,197,94,0.15);color:#22c55e}
|
|
.badge.flagship{background:rgba(168,85,247,0.15);color:#c084fc}
|
|
.badge.internal{background:rgba(6,182,212,0.12);color:#06b6d4}
|
|
|
|
.footer{margin-top:30px;padding:14px;text-align:center;color:#64748b;font-size:0.8rem;
|
|
border-top:1px solid rgba(100,116,139,0.15)}
|
|
.footer a{color:#06b6d4;text-decoration:none;margin:0 8px}
|
|
</style><!-- DOCTRINE-60-UX-ENRICH direct-inject-20260424-141837 -->
|
|
<style id="doctrine60-ux-direct">
|
|
|
|
/* DOCTRINE-60-UX-ENRICH injected-direct */
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
top: 0; left: 0; width: 100vw; height: 100vh;
|
|
background: radial-gradient(circle at 50% 50%, rgba(100,180,255,0.08), transparent 60%);
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
}
|
|
.card, .kpi, .panel, .btn {
|
|
transition: all 0.3s cubic-bezier(0.2,0,0.1,1);
|
|
}
|
|
.card:hover, .kpi:hover, .panel:hover {
|
|
box-shadow: 0 4px 20px rgba(100,180,255,0.2);
|
|
border-color: rgba(100,180,255,0.5);
|
|
}
|
|
@keyframes pulseD60 {
|
|
0%,100% { opacity: 1; transform: scale(1); }
|
|
50% { opacity: 0.7; transform: scale(1.05); }
|
|
}
|
|
.pulse, .live-indicator, .active, .online {
|
|
animation: pulseD60 3s ease-in-out infinite;
|
|
}
|
|
.modal, .chat, .speech, .overlay {
|
|
backdrop-filter: blur(12px);
|
|
-webkit-backdrop-filter: blur(12px);
|
|
}
|
|
.enter-stagger {
|
|
animation: enterStagD60 0.5s cubic-bezier(0.2,0,0.1,1) forwards;
|
|
}
|
|
@keyframes enterStagD60 {
|
|
from { opacity: 0; transform: translateY(20px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
</style>
|
|
</head><body>
|
|
<div class="container">
|
|
<h1>📊 Dashboards Index · Consolidated</h1>
|
|
<p class="subtitle">Point d'entrée unique · 17 dashboards organisés par catégorie · Source de vérité unique</p>
|
|
<div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px;font-size:0.75rem">
|
|
<a href="https://github.com/Yacineutt/weval-consulting/releases/tag/opus-session-20260421-v11-GOLIVE" style="background:linear-gradient(135deg,#22c55e,#16a34a);color:#fff;padding:4px 12px;border-radius:12px;text-decoration:none;font-weight:800;letter-spacing:0.5px">🏆 v11 GOLIVE CERTIFIED</a>
|
|
<span style="background:rgba(6,182,212,0.15);color:#06b6d4;padding:4px 10px;border-radius:12px;font-weight:700">11 releases</span>
|
|
<span style="background:rgba(168,85,247,0.15);color:#c084fc;padding:4px 10px;border-radius:12px;font-weight:700">47+ commits</span>
|
|
<span style="background:rgba(236,72,153,0.15);color:#ec4899;padding:4px 10px;border-radius:12px;font-weight:700">635 tools</span>
|
|
<span style="background:rgba(251,146,60,0.15);color:#fb923c;padding:4px 10px;border-radius:12px;font-weight:700">KPI 12/12</span>
|
|
</div>
|
|
|
|
<section class="hero">
|
|
<div class="hero-stats">
|
|
<div class="stat"><div class="stat-val success" id="stat-dashboards">17</div><div class="stat-lbl">Dashboards</div></div>
|
|
<div class="stat"><div class="stat-val info" id="stat-dock">—</div><div class="stat-lbl">Dock Coverage</div></div>
|
|
<div class="stat"><div class="stat-val success" id="stat-nonreg">—</div><div class="stat-lbl">NonReg</div></div>
|
|
<div class="stat"><div class="stat-val purple" id="stat-arch">—</div><div class="stat-lbl">Architecture</div></div>
|
|
<div class="stat"><div class="stat-val" id="stat-health">—</div><div class="stat-lbl">Token Health</div></div>
|
|
<div class="stat"><div class="stat-val info" id="stat-providers">—</div><div class="stat-lbl">Providers</div></div>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="filters">
|
|
<div class="filter active" data-cat="all">Tous</div>
|
|
<div class="filter" data-cat="command">🎛 Command</div>
|
|
<div class="filter" data-cat="monitor">📡 Monitor</div>
|
|
<div class="filter" data-cat="business">💼 Business</div>
|
|
<div class="filter" data-cat="infra">🖥 Infra</div>
|
|
<div class="filter" data-cat="arch">🏗 Architecture</div>
|
|
<div class="filter" data-cat="session">🏆 Session</div>
|
|
</div>
|
|
|
|
<div class="section-title">🎛 Command Centers</div>
|
|
<div class="grid" id="grid-command">
|
|
<a href="/weval-technology-platform.html" class="card" data-cat="command">
|
|
<div class="card-header"><span class="card-icon">🏛</span><span class="card-title">WTP ERP Global</span></div>
|
|
<div class="card-desc">Point d'entrée de toute l'architecture · 16 modules ERP consolidés</div>
|
|
<div class="card-meta"><span class="badge flagship">FLAGSHIP</span></div>
|
|
</a>
|
|
<a href="/command-center.html" class="card" data-cat="command">
|
|
<div class="card-header"><span class="card-icon">🎛</span><span class="card-title">Command Center</span></div>
|
|
<div class="card-desc">Centre de commande opérationnel global · 59KB rich</div>
|
|
</a>
|
|
<a href="/dg-command-center.html" class="card" data-cat="command">
|
|
<div class="card-header"><span class="card-icon">👔</span><span class="card-title">DG Command Center</span></div>
|
|
<div class="card-desc">Direction Générale · KPI executive · pilotage stratégique</div>
|
|
</a>
|
|
<a href="/mega-command-center.html" class="card" data-cat="command">
|
|
<div class="card-header"><span class="card-icon">🌐</span><span class="card-title">Mega Command Center</span></div>
|
|
<div class="card-desc">Super dashboard cross-functional</div>
|
|
</a>
|
|
<a href="/wevia-master.html" class="card" data-cat="command">
|
|
<div class="card-header"><span class="card-icon">🧠</span><span class="card-title">WEVIA Master</span></div>
|
|
<div class="card-desc">Chat autonome multi-agent · 630 tools registry</div>
|
|
<div class="card-meta"><span class="badge flagship">BRAIN</span></div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="section-title">📡 Monitors</div>
|
|
<div class="grid">
|
|
<a href="/claude-monitor.html" class="card" data-cat="monitor">
|
|
<div class="card-header"><span class="card-icon">🤖</span><span class="card-title">Claude Monitor</span></div>
|
|
<div class="card-desc">Opus & Sonnet agents activity tracking</div>
|
|
</a>
|
|
<a href="/ethica-monitor.html" class="card" data-cat="monitor">
|
|
<div class="card-header"><span class="card-icon">💊</span><span class="card-title">Ethica Monitor</span></div>
|
|
<div class="card-desc">Pipeline HCP + emails + B2B campaigns</div>
|
|
</a>
|
|
<a href="/realtime-monitor.html" class="card" data-cat="monitor">
|
|
<div class="card-header"><span class="card-icon">⚡</span><span class="card-title">Realtime Monitor</span></div>
|
|
<div class="card-desc">Live events + alerts streaming</div>
|
|
</a>
|
|
<a href="/crons-monitor.html" class="card" data-cat="monitor">
|
|
<div class="card-header"><span class="card-icon">⏰</span><span class="card-title">Crons Monitor</span></div>
|
|
<div class="card-desc">37 crons S204 + 38 crons S95 status</div>
|
|
</a>
|
|
<a href="/cyber-monitor.html" class="card" data-cat="monitor">
|
|
<div class="card-header"><span class="card-icon">🔒</span><span class="card-title">Cyber Monitor</span></div>
|
|
<div class="card-desc">CrowdSec + fail2ban + SSL + CVE scan</div>
|
|
</a>
|
|
<a href="/crons-monitor.html" class="card" data-cat="monitor">
|
|
<div class="card-header"><span class="card-icon">⏲</span><span class="card-title">Crons Monitor</span></div>
|
|
<div class="card-desc">35 crons S204 · heartbeat + timestamp last run</div>
|
|
</a>
|
|
<a href="/infra-command.html" class="card" data-cat="monitor">
|
|
<div class="card-header"><span class="card-icon">🏭</span><span class="card-title">Infra Command</span></div>
|
|
<div class="card-desc">Ports · services · disk · memory · CPU load</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="section-title">🏗 Architecture & Session</div>
|
|
<div class="grid">
|
|
<a href="/wtp-udock-coverage.html" class="card" data-cat="arch">
|
|
<div class="card-header"><span class="card-icon">🔗</span><span class="card-title">Dock Coverage</span></div>
|
|
<div class="card-desc">Navigation dock unifié · 276/276 = 100% internes</div>
|
|
<div class="card-meta"><span class="badge new">NEW</span></div>
|
|
</a>
|
|
<a href="/token-health-dashboard.html" class="card" data-cat="arch">
|
|
<div class="card-header"><span class="card-icon">🔑</span><span class="card-title">Token Health</span></div>
|
|
<div class="card-desc">17 providers monitoring · runbook rotation</div>
|
|
<div class="card-meta"><span class="badge new">NEW</span></div>
|
|
</a>
|
|
<a href="/architecture.html" class="card" data-cat="arch">
|
|
<div class="card-header"><span class="card-icon">🏗</span><span class="card-title">Architecture</span></div>
|
|
<div class="card-desc">Vue d'ensemble archi · 4 serveurs · L99</div>
|
|
</a>
|
|
<a href="/orphans-hub.html" class="card" data-cat="arch">
|
|
<div class="card-header"><span class="card-icon">📎</span><span class="card-title">Orphans Hub</span></div>
|
|
<div class="card-desc">Pages rebranchées · authority = 0 orphans</div>
|
|
</a>
|
|
<a href="/wiki.html" class="card" data-cat="session">
|
|
<div class="card-header"><span class="card-icon">📘</span><span class="card-title">Wiki</span></div>
|
|
<div class="card-desc">Knowledge base + Session Control Center live</div>
|
|
</a>
|
|
<a href="/nonreg.html" class="card" data-cat="session">
|
|
<div class="card-header"><span class="card-icon">✅</span><span class="card-title">NonReg Dashboard</span></div>
|
|
<div class="card-desc">153/153 tests stable 12 tours</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="section-title">💼 Business & Finance</div>
|
|
<div class="grid">
|
|
<a href="/business-kpi-dashboard.php" class="card" data-cat="business">
|
|
<div class="card-header"><span class="card-icon">💼</span><span class="card-title">Business KPI</span></div>
|
|
<div class="card-desc">V83 · 7 catégories · 56 KPIs</div>
|
|
</a>
|
|
<a href="/sales-hub.html" class="card" data-cat="business">
|
|
<div class="card-header"><span class="card-icon">💰</span><span class="card-title">Sales Hub</span></div>
|
|
<div class="card-desc">Pipeline CRM + leads segmentation</div>
|
|
</a>
|
|
<a href="/growth-engine.html" class="card" data-cat="business">
|
|
<div class="card-header"><span class="card-icon">📈</span><span class="card-title">Growth Engine</span></div>
|
|
<div class="card-desc">Acquisition + conversion + retention</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="section-title">🖥 Infrastructure</div>
|
|
<div class="grid">
|
|
<a href="/infra-command.html" class="card" data-cat="infra">
|
|
<div class="card-header"><span class="card-icon">🖥</span><span class="card-title">Infra Command</span></div>
|
|
<div class="card-desc">S204 + S95 servers · ports · services</div>
|
|
</a>
|
|
<a href="/blade-control.html" class="card" data-cat="infra">
|
|
<div class="card-header"><span class="card-icon">🗡</span><span class="card-title">Blade Control</span></div>
|
|
<div class="card-desc">Razer Blade Windows · auto-sync 60s agent</div>
|
|
</a>
|
|
<a href="/cron-control.html" class="card" data-cat="infra">
|
|
<div class="card-header"><span class="card-icon">🛠</span><span class="card-title">Cron Control</span></div>
|
|
<div class="card-desc">Crons lifecycle + force run</div>
|
|
</a>
|
|
<a href="/wevia-go-live.html" class="card" data-cat="infra">
|
|
<div class="card-header"><span class="card-icon">🚀</span><span class="card-title">WEVIA Go-Live</span></div>
|
|
<div class="card-desc">Deployment + release checklist</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="section-title">🧬 OSS Catalog</div>
|
|
<div class="grid">
|
|
<a href="/oss-catalog.html" class="card" data-cat="session">
|
|
<div class="card-header"><span class="card-icon">🧬</span><span class="card-title">OSS Catalog</span></div>
|
|
<div class="card-desc">78 tools · 7 categories · 14 Docker UP · 13 AI Frameworks · 16 WEVAL Custom</div>
|
|
<div class="card-meta"><span class="badge new">NEW v13</span></div>
|
|
</a>
|
|
<a href="/api/oss-registry.json" class="card" data-cat="session" target="_blank">
|
|
<div class="card-header"><span class="card-icon">📋</span><span class="card-title">OSS Registry JSON</span></div>
|
|
<div class="card-desc">Manifest complet · WEVIA Master tool oss_catalog</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="section-title">🧠 Learning & Analytics</div>
|
|
<div class="grid">
|
|
<a href="/learning-dashboard.html" class="card" data-cat="session">
|
|
<div class="card-header"><span class="card-icon">🧠</span><span class="card-title">Learning Analytics</span></div>
|
|
<div class="card-desc">Stats 24h par chatbot · intents distribution · latest learnings · ai_learning_log</div>
|
|
<div class="card-meta"><span class="badge new">NEW v22</span></div>
|
|
</a>
|
|
<a href="/api/learning-analytics.php" class="card" data-cat="session" target="_blank">
|
|
<div class="card-header"><span class="card-icon">📊</span><span class="card-title">Learning API JSON</span></div>
|
|
<div class="card-desc">Raw data 24h · summary + chatbots + intents + latest 10</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="section-title">🏆 Session & Certifications</div>
|
|
<div class="grid">
|
|
<a href="/api/session-opus-20260421-summary.json" class="card" data-cat="session" target="_blank">
|
|
<div class="card-header"><span class="card-icon">🏆</span><span class="card-title">GOLIVE Certificate v11</span></div>
|
|
<div class="card-desc">Session 21-avr · 11 releases · 47+ commits · 25/25 E2E · JSON summary</div>
|
|
<div class="card-meta"><span class="badge new">CERTIFIED</span></div>
|
|
</a>
|
|
<a href="/api/wtp-kpi-global-v2.php" class="card" data-cat="session" target="_blank">
|
|
<div class="card-header"><span class="card-icon">📈</span><span class="card-title">KPI v2.1 Unified</span></div>
|
|
<div class="card-desc">12/12 fields · 8 sources fusionnées · cache 30s · live aggregator</div>
|
|
<div class="card-meta"><span class="badge flagship">100%</span></div>
|
|
</a>
|
|
<a href="/api/playwright-golive-session-20260421.json" class="card" data-cat="session" target="_blank">
|
|
<div class="card-header"><span class="card-icon">🎭</span><span class="card-title">Playwright E2E Report</span></div>
|
|
<div class="card-desc">25 tests · public + auth + dashboards + APIs · structured report</div>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<a href="/">Home</a> · <a href="/wiki.html">Wiki</a> · <a href="/weval-technology-platform.html">WTP</a> · <a href="/wevia-master.html">WEVIA Master</a>
|
|
<br><br>
|
|
Point de vérité unique · Session Opus 21-avr-2026 · <a href="/api/wtp-kpi-global.php">KPI API</a>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Filters
|
|
document.querySelectorAll('.filter').forEach(f => {
|
|
f.addEventListener('click', () => {
|
|
document.querySelectorAll('.filter').forEach(x => x.classList.remove('active'));
|
|
f.classList.add('active');
|
|
const cat = f.dataset.cat;
|
|
document.querySelectorAll('.card').forEach(c => {
|
|
c.style.display = (cat === 'all' || c.dataset.cat === cat) ? '' : 'none';
|
|
});
|
|
});
|
|
});
|
|
|
|
// Live KPI hero
|
|
fetch('/api/wtp-kpi-global.php', {cache:'no-store'})
|
|
.then(r => r.json())
|
|
.then(d => {
|
|
const s = d.synthesis || {};
|
|
document.getElementById('stat-dock').textContent = s.dock_coverage_pct + '%';
|
|
document.getElementById('stat-nonreg').textContent = s.nonreg_pct + '%';
|
|
document.getElementById('stat-arch').textContent = s.arch_score + '/100';
|
|
|
|
const prov = (s.providers_active || 13) + '/13';
|
|
document.getElementById('stat-providers').textContent = prov;
|
|
})
|
|
.catch(e => console.error('KPI fetch:', e));
|
|
|
|
fetch('/api/token-rotate-orchestrator.php', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({action:'scan'})})
|
|
.then(r => r.json())
|
|
.then(d => {
|
|
const h = d.health_pct + '%';
|
|
const el = document.getElementById('stat-health');
|
|
el.textContent = h;
|
|
el.className = 'stat-val ' + (d.health_pct >= 80 ? 'success' : d.health_pct >= 60 ? 'warn' : 'info');
|
|
})
|
|
.catch(e => console.error('token fetch:', e));
|
|
</script>
|
|
|
|
<!-- WTP_UDOCK_V1 (Opus 21-avr t40) -->
|
|
<script src="/wtp-unified-dock.js" defer></script>
|
|
<script src="/opus-antioverlap-doctrine.js?v=1776806662" defer></script>
|
|
<!-- DOCTRINE-60-UX-JS --><script id="doctrine60-ux-js-direct">
|
|
|
|
// DOCTRINE-60-UX-JS staggered entrance
|
|
(function(){
|
|
if (!('IntersectionObserver' in window)) return;
|
|
const obs = new IntersectionObserver((entries) => {
|
|
entries.forEach((e, i) => {
|
|
if (e.isIntersecting) {
|
|
setTimeout(() => e.target.classList.add('enter-stagger'), i * 80);
|
|
obs.unobserve(e.target);
|
|
}
|
|
});
|
|
});
|
|
document.querySelectorAll('.card, .kpi, .panel').forEach(el => obs.observe(el));
|
|
})();
|
|
|
|
</script>
|
|
</body></html>
|