184 lines
9.8 KiB
HTML
184 lines
9.8 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fr"><head>
|
||
<meta charset="UTF-8">
|
||
<title>DMAIC Tracker NEW — WEVAL Lean 6σ</title>
|
||
<style>
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
body{font-family:-apple-system,sans-serif;background:#0a0e1a;color:#e2e8f0;padding:20px}
|
||
.hd{background:linear-gradient(135deg,#10b981 0%,#047857 100%);padding:20px;border-radius:12px;margin-bottom:20px}
|
||
h1{color:white;font-size:22px}
|
||
.hd .sub{color:rgba(255,255,255,.9);font-size:12px;margin-top:4px}
|
||
.phases{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-bottom:20px}
|
||
.phase{background:#111827;border:1px solid #1e293b;border-radius:10px;padding:14px;text-align:center}
|
||
.phase-letter{font-size:42px;font-weight:700;color:#10b981;font-family:'JetBrains Mono',monospace}
|
||
.phase-name{font-size:11px;color:#94a3b8;text-transform:uppercase;margin:4px 0 8px;letter-spacing:1px}
|
||
.phase-count{background:rgba(16,185,129,.15);color:#10b981;padding:4px 8px;border-radius:4px;font-size:11px;font-weight:600;display:inline-block}
|
||
.cycles{display:grid;grid-template-columns:repeat(auto-fit,minmax(360px,1fr));gap:12px}
|
||
.cycle{background:#111827;border:1px solid #1e293b;border-radius:10px;padding:14px}
|
||
.cycle h3{font-size:13px;color:#10b981;margin-bottom:8px}
|
||
.progress{display:flex;gap:2px;margin:8px 0}
|
||
.prog-bar{flex:1;height:6px;border-radius:3px;background:#1e293b}
|
||
.prog-bar.done{background:#10b981}
|
||
.prog-bar.current{background:#f59e0b;animation:pulse 2s infinite}
|
||
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
|
||
.meta{font-size:10px;color:#64748b;margin-top:8px}
|
||
</style>
|
||
</head><body>
|
||
<div class="hd">
|
||
<h1>📊 DMAIC Tracker — Lean 6σ Measure Continu</h1>
|
||
<div class="sub">Define · Measure · Analyze · Improve · Control · Zéro défaut · 153/153 NonReg · 99.7% L99</div>
|
||
</div>
|
||
|
||
<div class="phases">
|
||
<div class="phase"><div class="phase-letter">D</div><div class="phase-name">Define</div><div class="phase-count">8 cycles</div></div>
|
||
<div class="phase"><div class="phase-letter">M</div><div class="phase-name">Measure</div><div class="phase-count">6 cycles</div></div>
|
||
<div class="phase"><div class="phase-letter">A</div><div class="phase-name">Analyze</div><div class="phase-count">4 cycles</div></div>
|
||
<div class="phase"><div class="phase-letter">I</div><div class="phase-name">Improve</div><div class="phase-count">3 cycles</div></div>
|
||
<div class="phase"><div class="phase-letter">C</div><div class="phase-name">Control</div><div class="phase-count">2 cycles</div></div>
|
||
</div>
|
||
|
||
<div class="cycles" id="c"></div>
|
||
|
||
<script>
|
||
const CYCLES = [
|
||
{n:'VSM Commerce - Lead Loss', dept:'Commerce', phase:3, metric:'Conv 3%→7%', target:'+4pp'},
|
||
{n:'Time to MEP Reduction', dept:'SI&Data', phase:4, metric:'MEP 4h→2h', target:'-50%'},
|
||
{n:'Ethica HCP Conv Pharma', dept:'Pharma', phase:2, metric:'Open rate 12%→25%', target:'2x'},
|
||
{n:'Invoice DSO Reduction', dept:'Finance', phase:3, metric:'DSO 45j→30j', target:'-33%'},
|
||
{n:'Incident Response P1', dept:'SI&Data', phase:5, metric:'MTTR 4h→1h30', target:'-62%'},
|
||
{n:'NPS Post-Mission', dept:'Commerce', phase:2, metric:'NPS 42→65', target:'+23pts'},
|
||
{n:'Hiring Cycle Engineer', dept:'RH', phase:1, metric:'Cycle 90j→45j', target:'-50%'},
|
||
{n:'Email Deliverability', dept:'Pharma', phase:2, metric:'Inbox 78%→95%', target:'+17pp'},
|
||
{n:'Ethica TN Pilot Launch', dept:'Sales (Ethica)', phase:1, metric:'Launch 21j', target:'ON TIME'},
|
||
{n:'Support Ticket Closing', dept:'Production', phase:4, metric:'Close 48h→24h', target:'-50%'},
|
||
{n:'RGPD Compliance Audit', dept:'Legal', phase:1, metric:'100% compliance', target:'0 gaps'},
|
||
{n:'Social Engagement', dept:'Comms', phase:3, metric:'Reach +15%', target:'+15%'}
|
||
];
|
||
|
||
const PHASES = ['D','M','A','I','C'];
|
||
|
||
document.getElementById('c').innerHTML = CYCLES.map(c => `
|
||
<div class="cycle">
|
||
<h3>${c.n}</h3>
|
||
<div class="progress">
|
||
${PHASES.map((p,i) => `<div class="prog-bar ${i+1 < c.phase ? 'done' : i+1 === c.phase ? 'current' : ''}" title="${p}"></div>`).join('')}
|
||
</div>
|
||
<div class="meta">📊 ${c.metric} · 🎯 ${c.target} · 🏢 ${c.dept} · Phase: ${PHASES[c.phase-1]} (${c.phase}/5)</div>
|
||
</div>`).join('');
|
||
</script>
|
||
|
||
<!-- === OPUS UNIVERSAL DRILL-DOWN v1 19avr — append-only, doctrine #14 === -->
|
||
<script>
|
||
(function(){
|
||
if (window.__opusUniversalDrill) return; window.__opusUniversalDrill = true;
|
||
var d = document;
|
||
var m = d.createElement('div');
|
||
m.id = 'opus-udrill';
|
||
m.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.82);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:99995;padding:20px;cursor:pointer';
|
||
var inner = d.createElement('div');
|
||
inner.id = 'opus-udrill-in';
|
||
inner.style.cssText = 'max-width:900px;width:100%;max-height:90vh;overflow:auto;background:#0b0d15;border:1px solid rgba(99,102,241,0.35);border-radius:14px;padding:28px;cursor:default;box-shadow:0 20px 60px rgba(0,0,0,0.6);color:#e2e8f0;font:14px/1.55 Inter,system-ui,sans-serif';
|
||
inner.addEventListener('click', function(e){ e.stopPropagation(); });
|
||
m.appendChild(inner);
|
||
m.addEventListener('click', function(){ m.style.display='none'; });
|
||
d.addEventListener('keydown', function(e){ if(e.key==='Escape') m.style.display='none'; });
|
||
(d.body || d.documentElement).appendChild(m);
|
||
|
||
function openCard(card) {
|
||
// Clone card content + show close btn + increase font-size
|
||
var html = '<div style="display:flex;justify-content:flex-end;margin-bottom:14px"><button id="opus-udrill-close" style="padding:6px 14px;background:#171b2a;border:1px solid rgba(99,102,241,0.25);color:#e2e8f0;border-radius:8px;cursor:pointer;font-size:12px">✕ Fermer (Esc)</button></div>';
|
||
html += '<div style="transform-origin:top left;font-size:1.05em">' + card.outerHTML + '</div>';
|
||
inner.innerHTML = html;
|
||
d.getElementById('opus-udrill-close').onclick = function(){ m.style.display='none'; };
|
||
m.style.display = 'flex';
|
||
}
|
||
|
||
function wire(root) {
|
||
var sels = '.card,[class*="card"],.kpi,[class*="kpi"],.stat,[class*="stat"],.tile,[class*="tile"],.metric,[class*="metric"],.widget,[class*="widget"]';
|
||
var cards = root.querySelectorAll(sels);
|
||
for (var i = 0; i < cards.length; i++) {
|
||
var c = cards[i];
|
||
if (c.__opusWired) continue;
|
||
if (c.closest('button, a, input, select, textarea, #opus-udrill')) continue;
|
||
var r = c.getBoundingClientRect();
|
||
if (r.width < 60 || r.height < 40) continue;
|
||
c.__opusWired = true;
|
||
c.style.cursor = 'pointer';
|
||
c.setAttribute('role','button');
|
||
c.setAttribute('tabindex','0');
|
||
c.addEventListener('click', function(ev){
|
||
// If a more-specific drill is already active (e.g. pp-card custom), let it handle
|
||
if (ev.target.closest('[data-pp-id]') && window.__opusDrillInit) return;
|
||
if (ev.target.closest('a,button,input,select')) return;
|
||
ev.preventDefault(); ev.stopPropagation();
|
||
openCard(this);
|
||
});
|
||
c.addEventListener('keydown', function(ev){ if(ev.key==='Enter'||ev.key===' '){ev.preventDefault();openCard(this);} });
|
||
}
|
||
}
|
||
|
||
// Initial + mutation observer
|
||
var initRun = function(){ wire(d.body || d.documentElement); };
|
||
if (d.readyState === 'loading') d.addEventListener('DOMContentLoaded', initRun);
|
||
else initRun();
|
||
var mo = new MutationObserver(function(muts){
|
||
var newCard = false;
|
||
for (var i=0;i<muts.length;i++) if (muts[i].addedNodes.length) { newCard = true; break; }
|
||
if (newCard) initRun();
|
||
});
|
||
mo.observe(d.body || d.documentElement, {childList:true, subtree:true});
|
||
})();
|
||
</script>
|
||
<!-- === OPUS UNIVERSAL DRILL-DOWN END === -->
|
||
|
||
|
||
<!-- === OPUS HONEST NR/L99 OVERLAY v1 19avr - append-only doctrine #14 === -->
|
||
<script>
|
||
(function(){
|
||
if (window.__opusHonestOverlay) return; window.__opusHonestOverlay = true;
|
||
async function updateHonestValues(){
|
||
try {
|
||
const r = await fetch('/api/l99-honest.php', {cache:'no-store'});
|
||
const d = await r.json();
|
||
if (!d.ok) return;
|
||
const realNR = `${d.combined.pass}/${d.combined.total}`;
|
||
const realSigma = d.sigma;
|
||
// Find elements showing the myth values
|
||
const mythRegex = /(153\/153|304\/304|NR status 153\/153|L99 status 304\/304|NR 153\/153|L99 304\/304)/g;
|
||
// Walk text nodes
|
||
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);
|
||
const toReplace = [];
|
||
let node;
|
||
while (node = walker.nextNode()) {
|
||
if (node.nodeValue && mythRegex.test(node.nodeValue)) toReplace.push(node);
|
||
}
|
||
toReplace.forEach(textNode => {
|
||
const parent = textNode.parentNode;
|
||
if (!parent || parent.hasAttribute('data-opus-honest-applied')) return;
|
||
const newText = textNode.nodeValue.replace(/153\/153/g, realNR).replace(/304\/304/g, realNR);
|
||
textNode.nodeValue = newText;
|
||
parent.setAttribute('data-opus-honest-applied', '1');
|
||
});
|
||
// Add a small badge bottom-right showing honest live status
|
||
if (!document.getElementById('opus-honest-badge')) {
|
||
const b = document.createElement('div');
|
||
b.id = 'opus-honest-badge';
|
||
b.style.cssText = 'position:fixed;bottom:12px;right:12px;background:linear-gradient(90deg,#14b8a6,#a855f7);color:#05060a;padding:6px 12px;font:10px/1.3 Inter,system-ui,sans-serif;font-weight:700;border-radius:8px;z-index:99993;box-shadow:0 4px 12px rgba(0,0,0,0.3);cursor:pointer;max-width:280px';
|
||
b.title = 'Cliquer pour détails';
|
||
b.innerHTML = `✓ NR ${realNR} · ${realSigma} live`;
|
||
b.onclick = () => {
|
||
alert(`HONEST NonReg (doctrine #4):\n\nmaster: ${d.master.pass}/${d.master.total}\nopus: ${d.opus.pass}/${d.opus.total}\ncombined: ${realNR}\nsigma: ${realSigma}\n\n${d.myth_153}\n${d.myth_304}`);
|
||
};
|
||
document.body.appendChild(b);
|
||
}
|
||
} catch(e){console.error('L99-honest fetch error:', e);}
|
||
}
|
||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateHonestValues);
|
||
else updateHonestValues();
|
||
setInterval(updateHonestValues, 90000);
|
||
})();
|
||
</script>
|
||
<!-- === OPUS HONEST END === -->
|
||
|
||
</body></html>
|