feat(paperclip-warnings w318): banner WARN auto-detect projets orange

CAUSE RACINE (Yacine: PAS UN SEUL WARN):
- Dashboard paperclip affichait 3 projets orange/warn (CF Bypass 65pct P1,
  Gemini UX 40pct P2, Ethica HCP 76pct P1) SANS alerte visuelle banner
- Users ne voient pas rapidement combien de projets attention requise

FIX wave 318:
1. CSS w318-warnings-banner (orange gradient + animation fadein + items)
2. JS w318-warn-detector:
   - Parse projects array (status=warn/down OR progress<80 OR P0/P1<90)
   - Injecte banner en haut avec icone + titre + liste items + count
   - Fallback banner vert ALL SYSTEMS NOMINAL si 0 warning
3. Insertion avant section Projets Pipeline (placement logique)
4. Styles premium: glow drop-shadow, hover effects, prio badges

Zero regression (CSS/JS additive uniquement)
Zero ecrasement (str_replace surgical)
GOLD backup gold_paperclip_warn_w318
chattr +i preserve
CF purge

User feedback-driven: banner visible = compliance UX doctrine 60
This commit is contained in:
Opus
2026-04-24 17:21:28 +02:00
parent 006d4dff4b
commit 956b95bf3c

View File

@@ -186,6 +186,44 @@ html body .stat-card::before, html body .metric-card::before, html body .hub-car
}
html body .kpi, html body [class*="card"] { position: relative !important; }
</style>
<style id="w318-warnings-banner">
/* W318 Warnings banner - doctrine premium UX */
.w318-warn-banner{
margin:16px 20px 8px;padding:14px 18px;
background:linear-gradient(135deg,rgba(255,159,67,0.08),rgba(255,107,107,0.06));
border:1px solid rgba(255,159,67,0.35);border-left:4px solid #ff9f43;
border-radius:10px;display:flex;align-items:center;gap:14px;
box-shadow:0 2px 12px rgba(255,159,67,0.12);
animation:w318fadein .4s ease;
font-family:'Inter',system-ui,sans-serif
}
@keyframes w318fadein{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}
.w318-warn-icon{font-size:22px;filter:drop-shadow(0 0 8px rgba(255,159,67,0.4))}
.w318-warn-content{flex:1;display:flex;flex-direction:column;gap:6px}
.w318-warn-title{font-weight:700;font-size:13px;letter-spacing:.4px;color:#ff9f43;text-transform:uppercase}
.w318-warn-list{display:flex;gap:10px;flex-wrap:wrap;margin-top:4px}
.w318-warn-item{
padding:5px 11px;background:rgba(255,159,67,0.12);
border:1px solid rgba(255,159,67,0.3);border-radius:5px;
font-size:11px;color:#ffb775;font-family:'JetBrains Mono',monospace;
display:flex;align-items:center;gap:6px;transition:.15s
}
.w318-warn-item:hover{background:rgba(255,159,67,0.22);border-color:#ff9f43}
.w318-warn-item .pct{font-weight:700;color:#ff9f43}
.w318-warn-item .prio{font-size:9px;padding:1px 5px;background:rgba(0,0,0,0.3);border-radius:3px;color:#fff}
.w318-warn-item .prio.P1{background:rgba(255,107,107,0.5)}
.w318-warn-item .prio.P2{background:rgba(255,159,67,0.5)}
.w318-warn-count{
padding:4px 10px;background:#ff9f43;color:#0a0c12;
border-radius:12px;font-weight:800;font-size:12px;letter-spacing:.5px
}
.w318-warn-ok{
margin:16px 20px 8px;padding:10px 16px;
background:rgba(92,219,149,0.06);border-left:3px solid #5cdb95;border-radius:6px;
color:#5cdb95;font-size:11px;font-family:'JetBrains Mono',monospace;
letter-spacing:.3px;display:flex;align-items:center;gap:10px
}
</style>
</head>
<body>
<div class="header">
@@ -367,5 +405,77 @@ document.addEventListener('DOMContentLoaded', () => {
});
});
</script>
<script id="w318-warn-detector">
(function(){
function injectWarnBanner(){
if(typeof projects==='undefined')return;
// Detect warnings: status='warn' OR progress < 80 OR P1 < 90
var warnings = projects.filter(function(p){
if(p.status==='warn' || p.status==='down') return true;
if(p.progress < 80) return true;
if((p.priority==='P1' || p.priority==='P0') && p.progress < 90) return true;
return false;
});
// Find target (just before projets pipeline section)
var pipelineHeader = Array.from(document.querySelectorAll('h2,h3,.section-title')).find(function(el){
return el.textContent.indexOf('Projets Pipeline') >= 0 || el.textContent.indexOf('Pipeline') >= 0;
});
// Or fallback: top of main content
var target = pipelineHeader ? pipelineHeader.closest('.panel,.card,section,div') : document.querySelector('main,.main-content,body>div');
if(!target) target = document.body.firstElementChild;
// Remove existing
var existing = document.getElementById('w318-banner');
if(existing) existing.remove();
if(warnings.length === 0){
var ok = document.createElement('div');
ok.id = 'w318-banner';
ok.className = 'w318-warn-ok';
ok.innerHTML = '<span>✓</span><span>ALL SYSTEMS NOMINAL — ' + projects.length + ' projets OK, zero warning</span>';
target.parentNode.insertBefore(ok, target);
return;
}
var banner = document.createElement('div');
banner.id = 'w318-banner';
banner.className = 'w318-warn-banner';
var items = warnings.map(function(w){
return '<span class="w318-warn-item">' +
'<span class="prio ' + (w.priority||'') + '">' + (w.priority||'?') + '</span>' +
'<span>' + w.name + '</span>' +
'<span class="pct">' + w.progress + '%</span>' +
'</span>';
}).join('');
banner.innerHTML =
'<span class="w318-warn-icon">⚠️</span>' +
'<div class="w318-warn-content">' +
'<div class="w318-warn-title">Projets nécessitant attention</div>' +
'<div class="w318-warn-list">' + items + '</div>' +
'</div>' +
'<span class="w318-warn-count">' + warnings.length + ' WARN</span>';
target.parentNode.insertBefore(banner, target);
}
// Run after DOMContentLoaded + wait for projects array
function tryInject(retries){
retries = retries || 0;
if(typeof projects !== 'undefined' && projects.length){
injectWarnBanner();
} else if(retries < 20){
setTimeout(function(){tryInject(retries+1);}, 150);
}
}
if(document.readyState === 'loading'){
document.addEventListener('DOMContentLoaded', function(){tryInject();});
} else {
tryInject();
}
})();
</script>
</body>
</html>