138 lines
5.7 KiB
HTML
138 lines
5.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>V132 Portfolio — 12 intents 100% routing proof</title>
|
|
<style>
|
|
:root{--bg:#fff;--text:#1a1f3a;--text-soft:#5a6480;--border:rgba(26,31,58,0.08);--accent:#00c896;--fail:#ef4444;--card-bg:#f8fafc}
|
|
*{box-sizing:border-box}
|
|
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--bg);color:var(--text);margin:0;padding:24px;line-height:1.5}
|
|
.wrap{max-width:1400px;margin:0 auto}
|
|
h1{font-size:28px;margin:0 0 8px;font-weight:700}
|
|
.sub{color:var(--text-soft);font-size:14px;margin-bottom:24px}
|
|
.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:32px}
|
|
.kpi{background:var(--card-bg);border:1px solid var(--border);border-radius:12px;padding:20px}
|
|
.kpi-label{color:var(--text-soft);font-size:12px;text-transform:uppercase;letter-spacing:0.5px;margin-bottom:8px}
|
|
.kpi-val{font-size:32px;font-weight:700;color:var(--text)}
|
|
.kpi-val.pass{color:var(--accent)}
|
|
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px}
|
|
.card{background:var(--card-bg);border:1px solid var(--border);border-radius:12px;overflow:hidden;transition:transform 0.2s}
|
|
.card:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,0,0,0.08)}
|
|
.card-head{padding:16px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between}
|
|
.card-name{font-weight:600;font-size:14px}
|
|
.badge-pass{background:var(--accent);color:#fff;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:600}
|
|
.badge-fail{background:var(--fail);color:#fff;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:600}
|
|
.card-img{width:100%;height:160px;object-fit:cover;display:block}
|
|
.card-body{padding:16px;font-size:12px}
|
|
.q{color:var(--text-soft);font-style:italic;margin-bottom:8px;font-size:12px}
|
|
.engine{color:var(--accent);font-weight:600;font-family:monospace;font-size:11px;word-break:break-all}
|
|
.foot{margin-top:32px;padding-top:16px;border-top:1px solid var(--border);color:var(--text-soft);font-size:12px;text-align:center}
|
|
</style>
|
|
<!-- DOCTRINE-60-UX-ENRICH direct-inject-20260424-144054 -->
|
|
<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="wrap">
|
|
<h1>V132 Portfolio — WEVIA Master 12 intents routing</h1>
|
|
<div class="sub">Playwright Chromium headless · Video recording · Screenshots · 2026-04-21 · Chain V125→V132 → 100% achieved</div>
|
|
|
|
<div class="kpis">
|
|
<div class="kpi"><div class="kpi-label">Tests</div><div class="kpi-val">12</div></div>
|
|
<div class="kpi"><div class="kpi-label">PASS</div><div class="kpi-val pass">12</div></div>
|
|
<div class="kpi"><div class="kpi-label">Score</div><div class="kpi-val pass">100%</div></div>
|
|
<div class="kpi"><div class="kpi-label">L99 NonReg</div><div class="kpi-val pass">153/153</div></div>
|
|
</div>
|
|
|
|
<div class="grid" id="grid"></div>
|
|
|
|
<div class="foot">
|
|
Chain corrections V125→V131 : +60 interrogatifs → Fix A chattr → Fix B dev_devops reindex → Fix C dev_mobile reindex → V132 Playwright visual proof<br>
|
|
Zero écrasement · Zero régression · GOLD backups préservés · Doctrine 4 honnêteté cascade
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
fetch('/api/playwright-v132-100-pct-portfolio/results.json')
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
const grid = document.getElementById('grid');
|
|
data.tests.forEach(t => {
|
|
const card = document.createElement('div');
|
|
card.className = 'card';
|
|
const badge = t.status === 'PASS' ? 'badge-pass' : 'badge-fail';
|
|
card.innerHTML = `
|
|
<div class="card-head">
|
|
<span class="card-name">${t.intent}</span>
|
|
<span class="${badge}">${t.status}</span>
|
|
</div>
|
|
<img class="card-img" src="/api/playwright-v132-100-pct-portfolio/screenshots/${t.intent}.png" alt="${t.intent}" loading="lazy"/>
|
|
<div class="card-body">
|
|
<div class="q">"${t.query}"</div>
|
|
<div class="engine">${t.engine}</div>
|
|
<div style="color:var(--text-soft);margin-top:6px;font-size:11px">⏱ ${t.elapsed_ms}ms</div>
|
|
</div>
|
|
`;
|
|
grid.appendChild(card);
|
|
});
|
|
});
|
|
</script>
|
|
<!-- WTP_UDOCK_V1 (Opus 21-avr t38 ·V132 recon) --><script src="/wtp-unified-dock.js" defer></script>
|
|
<script src="/opus-antioverlap-doctrine.js?v=1776776094" 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>
|