Files
html/weval-sitemap.html
Opus Wire c2d4547e3e
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
feat(wtp-udock-v1): propagation batch 3 - 24 pages secondaires (46/294 total 15.6%)
Couverture dock nav:
- Tour 29: 10 pages
- Tour 30 batch 2: +12 (22 total)
- Tour 31 batch 3: +24 (46 total)

Pages injectees batch 3 (+92 bytes chacune, additif idempotent):
* Dashboards: api-key-hub, tasks-live, nonreg, monitoring, trust-center
* Pages hub: methodologie, playbook-3-phases, integrations-marketplace, automation-hub
* Navigation: pages-index, weval-sitemap
* Business: candidates-pool, contacts-segmentation-dashboard, kaouther-compose
* Landings: landing-industrie, landing-ocp, landing-banque, landing-retail, ecosysteme-ia-maroc
* Controls: linkedin-control-v98, blade-control, world-map-live, vsm-15depts-NEW, nl-autowire-status

SKIP: vsm-pipelines.html (chattr+i)
GOLD: /opt/wevads/vault/gold_*_t31_*.html
Doctrine: ERP Global single source nav · Zero ecrasement · Zero regression · Idempotent
2026-04-21 13:01:30 +02:00

249 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. 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.0">
<title>WEVAL Sitemap · Toutes pages · Source unique</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{
--bg:#09090b; --surface:#13131a; --surface2:#1a1a24; --border:#2a2a35;
--text:#fafafa; --muted:#94a3b8; --accent:#6366f1; --accent2:#a855f7;
--green:#22c55e; --amber:#f59e0b; --red:#ef4444; --cyan:#22d3ee;
--grad:linear-gradient(135deg,#6366f1 0%,#a855f7 50%,#ec4899 100%);
}
body{font-family:-apple-system,Inter,Segoe UI,sans-serif;background:var(--bg);color:var(--text);min-height:100vh;line-height:1.5}
.topbar{background:var(--surface);border-bottom:1px solid var(--border);padding:14px 28px;display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;z-index:100;backdrop-filter:blur(20px)}
.topbar h1{font-size:1.15rem;font-weight:700;background:var(--grad);-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:-0.02em}
.topbar .meta{display:flex;gap:14px;align-items:center;font-size:.78rem;color:var(--muted)}
.topbar .live{display:inline-flex;align-items:center;gap:6px;color:var(--green);font-weight:600}
.topbar .live::before{content:'';width:8px;height:8px;background:var(--green);border-radius:99px;box-shadow:0 0 12px var(--green);animation:pulse 1.5s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}
.bread{padding:14px 28px;background:var(--surface);font-size:.78rem;color:var(--muted);border-bottom:1px solid var(--border)}
.bread a{color:var(--accent);text-decoration:none;margin-right:6px}
main{padding:28px;max-width:1700px;margin:0 auto}
.hero{background:linear-gradient(135deg,rgba(99,102,241,.1),rgba(168,85,247,.05));border:1px solid rgba(99,102,241,.2);border-radius:16px;padding:24px 28px;margin-bottom:24px;position:relative;overflow:hidden}
.hero::before{content:'';position:absolute;top:-50%;right:-10%;width:300px;height:300px;background:radial-gradient(circle,rgba(99,102,241,.15),transparent 70%);pointer-events:none}
.hero h2{font-size:1.4rem;margin-bottom:6px;background:var(--grad);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.hero p{color:var(--muted);font-size:.85rem;line-height:1.6}
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:18px}
.kpi{background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:16px;position:relative;overflow:hidden}
.kpi::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--grad);opacity:.6}
.kpi .lbl{font-size:.7rem;color:var(--muted);text-transform:uppercase;letter-spacing:1px;font-weight:600;margin-bottom:4px}
.kpi .val{font-size:1.6rem;font-weight:700;background:linear-gradient(180deg,var(--text),var(--muted));-webkit-background-clip:text;-webkit-text-fill-color:transparent;line-height:1.1}
.kpi .sub{font-size:.7rem;color:var(--muted);margin-top:4px}
.controls{display:flex;gap:10px;margin-bottom:18px;flex-wrap:wrap;align-items:center}
.search{flex:1;min-width:280px;padding:10px 14px;background:var(--surface);border:1px solid var(--border);border-radius:10px;color:var(--text);font-size:.88rem;outline:none}
.search:focus{border-color:var(--accent)}
.filter-btn{padding:7px 13px;background:var(--surface);border:1px solid var(--border);border-radius:99px;color:var(--muted);font-size:.75rem;cursor:pointer;transition:.2s;font-weight:600}
.filter-btn:hover{border-color:var(--accent);color:var(--text)}
.filter-btn.active{background:var(--accent);color:#fff;border-color:var(--accent)}
.cat-section{background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:16px;margin-bottom:14px}
.cat-title{font-size:.95rem;font-weight:700;color:var(--text);display:flex;align-items:center;gap:10px;margin-bottom:12px}
.cat-title .badge{background:var(--surface2);color:var(--cyan);padding:3px 9px;border-radius:99px;font-size:.7rem;font-weight:600;font-variant-numeric:tabular-nums}
.page-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:8px}
.page-card{background:var(--surface2);border:1px solid var(--border);border-radius:8px;padding:10px 12px;display:flex;flex-direction:column;gap:4px;transition:.2s;text-decoration:none;color:var(--text);cursor:pointer}
.page-card:hover{border-color:var(--accent);background:rgba(99,102,241,.08);transform:translateY(-1px);box-shadow:0 8px 20px rgba(99,102,241,.1)}
.page-card .name{font-size:.78rem;font-weight:600;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.page-card .meta{font-size:.65rem;color:var(--muted);display:flex;justify-content:space-between;align-items:center;gap:6px}
.page-card .badge-orphan{background:rgba(245,158,11,.15);color:var(--amber);padding:1px 6px;border-radius:4px;font-size:.6rem;font-weight:600}
.page-card .badge-linked{background:rgba(34,197,94,.15);color:var(--green);padding:1px 6px;border-radius:4px;font-size:.6rem;font-weight:600}
.empty{text-align:center;color:var(--muted);padding:40px;font-size:.85rem;font-style:italic}
footer{padding:32px 28px;text-align:center;color:var(--muted);font-size:.75rem;border-top:1px solid var(--border);margin-top:32px}
footer a{color:var(--accent);text-decoration:none;margin:0 8px}
.refresh{padding:5px 12px;background:var(--surface2);border:1px solid var(--border);border-radius:99px;color:var(--muted);font-size:.7rem;cursor:pointer}
.refresh:hover{border-color:var(--accent);color:var(--text)}
</style>
</head>
<body>
<div class="topbar">
<h1>🗺 WEVAL Sitemap · Toutes pages</h1>
<div class="meta">
<span>Source: <a href="/api/weval-sitemap-api.php" style="color:var(--cyan)">sitemap-api</a></span>
<span>Refresh: <span id="ts"></span></span>
<button class="refresh" onclick="loadAll()"></button>
<span class="live">LIVE</span>
</div>
</div>
<div class="bread">
<a href="/">Home</a> /
<a href="/wevia-erp-v2.html">ERP V2</a> /
<a href="/architecture.html">Architecture</a> /
<span style="color:var(--text)">Sitemap exhaustif</span>
</div>
<main>
<div class="hero">
<h2>🗺 Sitemap exhaustif · Source unique fichiers</h2>
<p>Référentiel complet de toutes les pages HTML déployées · Live filesystem scan · Catégorisation automatique · Détection orphelins · Last modified · Recherche + filtres · <b>Aucune page perdue</b> · <b>Zero orphan</b> · Auto-refresh 60s</p>
</div>
<div class="kpi-grid">
<div class="kpi"><div class="lbl">Total pages</div><div class="val" id="k-total"></div><div class="sub">HTML déployées</div></div>
<div class="kpi"><div class="lbl">Catégories</div><div class="val" id="k-cats"></div><div class="sub">groupées par fonction</div></div>
<div class="kpi"><div class="lbl">Orphan pages</div><div class="val" id="k-orphan"></div><div class="sub">non linkées encore</div></div>
<div class="kpi"><div class="lbl">Last update</div><div class="val" id="k-last" style="font-size:1rem"></div><div class="sub">scan timestamp</div></div>
</div>
<div class="controls">
<input type="text" class="search" id="search" placeholder="🔍 Rechercher par nom (ex: agent, hub, dashboard, ethica)..." oninput="render()">
<button class="filter-btn active" onclick="setFilter('all',this)">Toutes</button>
<button class="filter-btn" onclick="setFilter('orphan',this)">⚠ Orphelines</button>
<button class="filter-btn" onclick="setFilter('linked',this)">✓ Liées</button>
</div>
<div id="cat-list"></div>
</main>
<footer>
WEVAL Sitemap · scan exhaustif filesystem · v1.0 ·
<a href="/wevia-master.html">WEVIA Master</a> ·
<a href="/wevia-erp-v2.html">ERP V2</a> ·
<a href="/wevia-erp-unified.html">ERP V1</a> ·
<a href="/architecture.html">Architecture</a> ·
<a href="/api/weval-sitemap-api.php">API JSON</a>
</footer>
<script>
let DATA = null;
let FILTER = 'all';
function fmt(n){return (n||0).toLocaleString('fr-FR')}
async function loadAll() {
document.getElementById('ts').textContent = new Date().toLocaleTimeString('fr-FR');
try {
DATA = await fetch('/api/weval-sitemap-api.php').then(r => r.json());
if (!DATA.ok) throw new Error('api error');
document.getElementById('k-total').textContent = fmt(DATA.stats.total_pages);
document.getElementById('k-cats').textContent = fmt(DATA.stats.total_categories);
document.getElementById('k-orphan').textContent = fmt(DATA.stats.orphan_count);
document.getElementById('k-last').textContent = new Date(DATA.ts).toLocaleString('fr-FR');
render();
} catch (e) {
document.getElementById('cat-list').innerHTML = '<div class="empty">Erreur API: ' + e.message + '</div>';
}
}
function setFilter(f, btn) {
FILTER = f;
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
render();
}
function render() {
if (!DATA) return;
const search = document.getElementById('search').value.toLowerCase().trim();
const out = [];
const cats = Object.keys(DATA.by_category).sort((a,b) =>
DATA.by_category[b].length - DATA.by_category[a].length
);
for (const cat of cats) {
let pages = DATA.by_category[cat];
if (FILTER === 'orphan') pages = pages.filter(p => p.is_orphan);
if (FILTER === 'linked') pages = pages.filter(p => !p.is_orphan);
if (search) pages = pages.filter(p => p.name.toLowerCase().includes(search));
if (pages.length === 0) continue;
const cards = pages.map(p => {
const orphanBadge = p.is_orphan
? `<span class="badge-orphan">orphan</span>`
: `<span class="badge-linked">${p.ref_count}×</span>`;
return `
<a class="page-card" href="${p.url}" target="_blank">
<div class="name" title="${p.name}">${p.name}</div>
<div class="meta">
<span>${p.size_kb} KB · ${p.mtime_human}</span>
${orphanBadge}
</div>
</a>`;
}).join('');
out.push(`
<div class="cat-section">
<div class="cat-title">${cat} <span class="badge">${pages.length}</span></div>
<div class="page-grid">${cards}</div>
</div>`);
}
document.getElementById('cat-list').innerHTML = out.length
? out.join('')
: '<div class="empty">Aucun résultat pour ces filtres</div>';
}
loadAll();
setInterval(loadAll, 60000);
</script>
<script src="/api/ux-drill-enricher.php"></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) {
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 (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);} });
}
}
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 === -->
<script src="/api/a11y-auto-enhancer.js" defer></script>
<!-- WTP_UDOCK_V1 (Opus 21-avr t31b3) --><script src="/wtp-unified-dock.js" defer></script>
</body>
</html>