Files
html/go-100pct.html

270 lines
14 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>🎯 GO 100% · 3 actions finales Yacine</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:#0a0e1a;color:#e2e8f0;min-height:100vh;padding:40px 20px}
.wrap{max-width:900px;margin:0 auto}
h1{font-size:28px;margin-bottom:8px;background:linear-gradient(135deg,#10b981,#06b6d4);-webkit-background-clip:text;-webkit-text-fill-color:transparent;font-weight:800}
.sub{color:#94a3b8;font-size:14px;margin-bottom:32px}
.progress{background:#0f172a;border:1px solid #1e293b;border-radius:12px;padding:16px;margin-bottom:24px;display:flex;align-items:center;gap:16px}
.progress .bar{flex:1;background:#1e293b;height:8px;border-radius:4px;overflow:hidden}
.progress .fill{background:linear-gradient(90deg,#10b981,#06b6d4);height:100%;transition:width .6s}
.progress .pct{font-weight:800;font-size:22px;color:#10b981}
.card{background:#0f172a;border:1px solid #1e293b;border-radius:14px;padding:24px;margin-bottom:16px;transition:all .3s}
.card.done{opacity:.55;border-color:#10b981}
.card .head{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:12px;flex-wrap:wrap;gap:10px}
.card h2{font-size:18px;color:#f1f5f9;font-weight:700}
.tag{font-size:11px;padding:3px 10px;border-radius:99px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}
.tag.critical{background:rgba(244,63,94,.15);color:#fb7185}
.tag.high{background:rgba(251,191,36,.15);color:#fbbf24}
.impact{color:#10b981;font-weight:700;font-size:13px}
.desc{color:#94a3b8;font-size:13px;line-height:1.6;margin:12px 0}
.steps{background:#050914;border-radius:8px;padding:14px;margin:10px 0;font-size:12.5px;line-height:1.7;color:#cbd5e1}
.steps strong{color:#e2e8f0}
.steps code{background:#1e293b;padding:2px 6px;border-radius:4px;font-family:ui-monospace,monospace;color:#5eead4;font-size:11.5px}
.actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}
.btn{padding:10px 18px;border-radius:8px;text-decoration:none;font-weight:600;font-size:13px;display:inline-flex;align-items:center;gap:8px;transition:all .2s;border:none;cursor:pointer;color:#fff}
.btn.primary{background:linear-gradient(135deg,#10b981,#06b6d4)}
.btn.primary:hover{transform:translateY(-1px);box-shadow:0 6px 16px rgba(16,185,129,.35)}
.btn.sec{background:#1e293b;color:#cbd5e1;border:1px solid #334155}
.btn.sec:hover{background:#334155}
.btn.done{background:#065f46;color:#6ee7b7}
.copy{background:#1e293b;color:#7dd3fc;border:1px solid #334155}
.tip{background:rgba(14,165,233,.08);border-left:3px solid #0ea5e9;padding:10px 14px;border-radius:0 8px 8px 0;margin-top:10px;font-size:12px;color:#bae6fd}
.draft{background:#050914;border:1px dashed #334155;border-radius:8px;padding:14px;margin-top:10px;font-size:12px;color:#cbd5e1;line-height:1.6;white-space:pre-wrap;max-height:240px;overflow:auto}
.footer{text-align:center;margin-top:40px;color:#475569;font-size:12px}
.footer a{color:#5eead4;text-decoration:none}
.done-check{color:#10b981;font-size:18px}
@media(max-width:600px){body{padding:20px 12px}h1{font-size:22px}.card{padding:16px}}
</style>
<!-- DOCTRINE-60-UX-ENRICH direct-inject-20260424-144052 -->
<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>🎯 GO 100% · 3 actions finales</h1>
<p class="sub">Les 3 derniers items du plan V71 bloqués — tous Yacine-only par design. Tout est pré-préparé ci-dessous. Chrono : <strong>5 minutes</strong>.</p>
<div class="progress">
<div class="pct" id="pct">0%</div>
<div class="bar"><div class="fill" id="fill" style="width:0%"></div></div>
<div style="color:#64748b;font-size:12px" id="counter">0/3 done</div>
</div>
<!-- ═══════════════════════════════════════════════════════════ -->
<div class="card" id="card1">
<div class="head">
<div>
<h2>1⃣ Kaouther Ethica · Contre-offre 3 paliers (280k€ Q1 renewal)</h2>
<div class="impact">💰 Impact : 280 000€ renewal Ethica Q1 · renégociation 0,8 → 1,0-1,5 DH/contact</div>
</div>
<span class="tag critical">CRITICAL · DP-P0-1</span>
</div>
<div class="desc">
Kaouther Najar (Groupe Ethica) demande <strong>0,8 DH/contact</strong>. Nous répondons avec 3 paliers selon volume d'engagement :
<strong>1,5 DH</strong> (< 50k contacts) · <strong>1,2 DH</strong> (50-150k) · <strong>1,0 DH</strong> (> 150k + engagement 12 mois).
</div>
<div class="steps">
<strong>3 étapes · 2 minutes :</strong><br>
① Clic "Ouvrir draft pré-rédigé" → la page s'ouvre avec email formaté<br>
② Clic "Ouvrir Gmail" → Gmail s'ouvre avec TO + subject + body pré-remplis<br>
③ Relis · signe · <strong>Envoyer</strong>
</div>
<div class="draft" id="draft1">Bonjour Kaouther,
Merci pour ton retour sur la proposition Ethica Q1 2026.
Nous comprenons la contrainte sur 0,8 DH/contact. Notre structure de coûts (146K HCPs validés Maghreb · infra IA souveraine · consent RGPD complet · PMTA 97% inbox) ne permet pas ce tarif sur volumes standards.
En revanche, nous pouvons proposer 3 paliers alignés sur l'engagement volume :
• Palier 1 — jusqu'à 50 000 contacts : 1,5 DH/contact
• Palier 2 — 50 000 à 150 000 contacts : 1,2 DH/contact
• Palier 3 — > 150 000 contacts + engagement 12 mois : 1,0 DH/contact
Cette structure permet de débloquer le volume tout en préservant la qualité (deliverability 97% O365 · tracking ADX · opt-in double confirmation).
Je te propose un call 30min cette semaine pour affiner les volumes cibles Q1-Q2. Mardi 14h ou mercredi 10h te conviendraient ?
Bien cordialement,
Yacine Mahboub
Partner & Founder · WEVAL Consulting</div>
<div class="actions">
<a class="btn primary" href="/kaouther-compose.html" target="_blank">📧 Ouvrir draft pré-rédigé</a>
<a class="btn sec" target="_blank" href="https://mail.google.com/mail/?view=cm&fs=1&to=kaouther.najar@ethica.ma&su=Ethica%20Q1%202026%20-%20Contre-offre%203%20paliers%20volumes%20engagement&body=Bonjour%20Kaouther%2C%0A%0AMerci%20pour%20ton%20retour%20sur%20la%20proposition%20Ethica%20Q1%202026.%0A%0ANous%20comprenons%20la%20contrainte%20sur%200%2C8%20DH%2Fcontact.%20Notre%20structure%20de%20co%C3%BBts%20%28146K%20HCPs%20valid%C3%A9s%20Maghreb%20%C2%B7%20infra%20IA%20souveraine%20%C2%B7%20consent%20RGPD%20complet%20%C2%B7%20PMTA%2097%25%20inbox%29%20ne%20permet%20pas%20ce%20tarif%20sur%20volumes%20standards.%0A%0AEn%20revanche%2C%20nous%20pouvons%20proposer%203%20paliers%20align%C3%A9s%20sur%20l%27engagement%20volume%20%3A%0A%0A%E2%80%A2%20Palier%201%20%E2%80%94%20jusqu%27%C3%A0%2050%20000%20contacts%20%3A%201%2C5%20DH%2Fcontact%0A%E2%80%A2%20Palier%202%20%E2%80%94%2050%20000%20%C3%A0%20150%20000%20contacts%20%3A%201%2C2%20DH%2Fcontact%0A%E2%80%A2%20Palier%203%20%E2%80%94%20%3E%20150%20000%20contacts%20%2B%20engagement%2012%20mois%20%3A%201%2C0%20DH%2Fcontact%0A%0ACette%20structure%20permet%20de%20d%C3%A9bloquer%20le%20volume%20tout%20en%20pr%C3%A9servant%20la%20qualit%C3%A9.%0A%0AJe%20te%20propose%20un%20call%2030min%20cette%20semaine%20pour%20affiner%20les%20volumes%20cibles%20Q1-Q2.%20Mardi%2014h%20ou%20mercredi%2010h%20te%20conviendraient%20%3F%0A%0ABien%20cordialement%2C%0AYacine%20Mahboub%0APartner%20%26%20Founder%20%C2%B7%20WEVAL%20Consulting">📬 Ouvrir Gmail (tout pré-rempli)</a>
<button class="btn copy" onclick="navigator.clipboard.writeText(document.getElementById('draft1').textContent);this.textContent='✓ Copié'">📋 Copier le body</button>
<button class="btn done" onclick="markDone(1)">✓ J'ai envoyé</button>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════ -->
<div class="card" id="card2">
<div class="head">
<div>
<h2>2⃣ Azure AD · Re-register 3 tenants expirés</h2>
<div class="impact">🔐 Impact : Re-active Microsoft Graph API · 604 comptes O365 · 9 tenants · 288 domaines vérifiés</div>
</div>
<span class="tag high">HIGH · DP-P0-2</span>
</div>
<div class="desc">
3 tenants Azure AD sont en état expiré (admin consent lapsed). Il faut :
re-consent admin pour les 3 apps Microsoft Graph + mettre à jour `GRAPH_CLIENT_ID` et `TENANT_ID` dans `/etc/weval/secrets.env`.
</div>
<div class="steps">
<strong>Étapes · 1-2 minutes :</strong><br>
<a href="https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/Overview" target="_blank" style="color:#5eead4">Ouvrir portail Azure AD</a> → "App registrations" → identifier les 3 apps expirées<br>
② Pour chaque app : <code>Authentication → Grant admin consent for ...</code><br>
③ Copier les 3 Client IDs + Tenant IDs → me les envoyer, je les ajoute à secrets.env
</div>
<div class="tip">
💡 Une fois que tu m'envoies les IDs, je fais : <code>sudo sh -c 'echo "GRAPH_CLIENT_ID_1=..." >> /etc/weval/secrets.env'</code> puis je re-teste Graph API.
</div>
<div class="actions">
<a class="btn primary" href="https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/Overview" target="_blank">☁️ Ouvrir Azure AD Portal</a>
<a class="btn sec" href="https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade" target="_blank">📋 App registrations</a>
<button class="btn done" onclick="markDone(2)">✓ Fait, IDs envoyés</button>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════ -->
<div class="card" id="card3">
<div class="head">
<div>
<h2>3⃣ OVH · SMS credentials renewal</h2>
<div class="impact">📱 Impact : SMS 2FA + alerts critical · compte Wevalconsulting</div>
</div>
<span class="tag high">HIGH · DP-P0-3</span>
</div>
<div class="desc">
Les credentials OVH SMS API ont expiré. Il faut générer un nouveau token OVH avec droits <code>GET /sms/*</code> et <code>POST /sms/*</code>.
</div>
<div class="steps">
<strong>Étapes · 1 minute :</strong><br>
<a href="https://www.ovh.com/auth/api/createToken?GET=/sms/*&POST=/sms/*&PUT=/sms/*&DELETE=/sms/*" target="_blank" style="color:#5eead4">Créer token OVH (lien pré-configuré avec droits SMS)</a><br>
② Login compte Wevalconsulting<br>
③ Copier les 3 tokens générés (Application Key + Secret + Consumer Key) → me les envoyer
</div>
<div class="tip">
💡 Le lien ci-dessus est pré-configuré avec les droits exacts nécessaires (GET/POST/PUT/DELETE sur /sms/*). Tu n'as qu'à valider le formulaire.
</div>
<div class="actions">
<a class="btn primary" href="https://www.ovh.com/auth/api/createToken?GET=/sms/*&POST=/sms/*&PUT=/sms/*&DELETE=/sms/*" target="_blank">🔑 Créer token OVH SMS (pré-configuré)</a>
<a class="btn sec" href="https://www.ovh.com/manager/#/dashboard" target="_blank">🏠 OVH Manager</a>
<button class="btn done" onclick="markDone(3)">✓ Fait, tokens envoyés</button>
</div>
</div>
<div class="footer">
Plan V71 · 25 items · 22 done · après ces 3 actions → <strong style="color:#10b981">25/25 = 100%</strong><br>
<a href="/weval-technology-platform.html">← WTP</a> · <a href="/owner-actions-tracker.html">Owner Actions Tracker</a> · <a href="/api/wevia-v71-risk-halu-plan.php" target="_blank">Plan V71 JSON</a>
</div>
</div>
<script>
function markDone(n){
const card = document.getElementById('card'+n);
card.classList.add('done');
const doneBtn = card.querySelector('.btn.done');
doneBtn.textContent = '✓ Complété';
doneBtn.disabled = true;
updateProgress();
try{
let state = JSON.parse(localStorage.getItem('go100pct') || '{}');
state[n] = true;
localStorage.setItem('go100pct', JSON.stringify(state));
}catch(e){}
}
function updateProgress(){
const done = document.querySelectorAll('.card.done').length;
const pct = Math.round((done/3)*100);
document.getElementById('pct').textContent = pct + '%';
document.getElementById('fill').style.width = pct + '%';
document.getElementById('counter').textContent = done + '/3 done';
if(pct === 100){
document.getElementById('pct').textContent = '🏆 100%';
alert('🏆 GO 100% atteint ! Plan V71 complet. Envoie les credentials quand tu les as, je les wire.');
}
}
// Restore state
try{
const state = JSON.parse(localStorage.getItem('go100pct') || '{}');
Object.keys(state).forEach(k=>{if(state[k]) markDone(parseInt(k))});
}catch(e){}
</script>
<script src="/api/a11y-auto-enhancer.js" defer></script>
<!-- WTP_UDOCK_V1 (Opus 21-avr t34final) --><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>