1670 lines
74 KiB
HTML
1670 lines
74 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="fr" data-version="V146">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>WePredict Cockpit · V146 · WEVAL ecosystem</title>
|
||
<meta name="description" content="Cockpit prédictif WEVAL — 4 piliers × 4 domaines · 16 cockpits · 64 prédictions · WEVIA · Products · Business · Infra">
|
||
<meta name="wevia-version" content="V146">
|
||
<meta name="wevia-preserve" content="mirofish.weval-consulting.com:v0.1-Preview">
|
||
<meta name="wevia-coverage" content="full-weval-ecosystem-not-sap-only">
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Unbounded:wght@300;400;500;600;700&family=Figtree:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||
|
||
<style>
|
||
:root{
|
||
--bg-void: #05070e;
|
||
--bg-base: #0a0e1a;
|
||
--bg-surface: #0e1424;
|
||
--bg-elev: #131a2e;
|
||
--bg-glass: rgba(20,27,47,0.55);
|
||
--bg-glass-strong: rgba(14,20,36,0.85);
|
||
|
||
--bd-hair: rgba(255,255,255,0.05);
|
||
--bd-soft: rgba(255,255,255,0.08);
|
||
--bd-mid: rgba(255,255,255,0.14);
|
||
--bd-strong: rgba(255,255,255,0.22);
|
||
|
||
--tx-1: #eef2ff;
|
||
--tx-2: #c7d0e5;
|
||
--tx-3: #8591af;
|
||
--tx-4: #5a6688;
|
||
--tx-dim: #3a4666;
|
||
|
||
/* 4 prediction levels */
|
||
--strat-1: #d946ef; --strat-2: #a855f7; --strat-glow: rgba(168,85,247,0.35);
|
||
--tact-1: #22d3ee; --tact-2: #3b82f6; --tact-glow: rgba(59,130,246,0.35);
|
||
--op-1: #84cc16; --op-2: #10b981; --op-glow: rgba(16,185,129,0.35);
|
||
--infra-1: #f59e0b; --infra-2: #ef4444; --infra-glow: rgba(245,158,11,0.35);
|
||
|
||
/* 4 WEVAL pillars — distinct from level colors */
|
||
--p-wevia-1: #7c3aed; --p-wevia-2: #ec4899; /* WEVIA sovereign AI */
|
||
--p-product-1: #06b6d4; --p-product-2: #14b8a6; /* WEVAL native products */
|
||
--p-biz-1: #f59e0b; --p-biz-2: #ec4899; /* Business SAP + sales */
|
||
--p-infra-1: #64748b; --p-infra-2: #475569; /* Cloud & infra */
|
||
|
||
/* Taxonomy badges */
|
||
--tax-wevia: #a855f7;
|
||
--tax-native: #14b8a6;
|
||
--tax-sap: #3b82f6;
|
||
--tax-hybrid: #f59e0b;
|
||
--tax-partner: #ec4899;
|
||
--tax-infra: #64748b;
|
||
|
||
--good: #34d399;
|
||
--warn: #fbbf24;
|
||
--bad: #f87171;
|
||
--neutral: #94a3b8;
|
||
|
||
--ff-display: 'Unbounded', ui-sans-serif, system-ui;
|
||
--ff-body: 'Figtree', ui-sans-serif, system-ui;
|
||
--ff-mono: 'JetBrains Mono', ui-monospace, monospace;
|
||
|
||
--r-sm: 8px; --r-md: 14px; --r-lg: 20px; --r-xl: 28px;
|
||
--ease: cubic-bezier(.2,.7,.1,1);
|
||
}
|
||
|
||
*,*::before,*::after{ box-sizing: border-box; }
|
||
html,body{ margin:0; padding:0; }
|
||
|
||
body{
|
||
background:
|
||
radial-gradient(1200px 700px at 85% -10%, rgba(168,85,247,0.08), transparent 60%),
|
||
radial-gradient(900px 600px at -10% 40%, rgba(20,184,166,0.07), transparent 55%),
|
||
radial-gradient(900px 500px at 110% 60%, rgba(245,158,11,0.05), transparent 60%),
|
||
radial-gradient(700px 400px at 50% 110%, rgba(100,116,139,0.06), transparent 60%),
|
||
var(--bg-void);
|
||
color: var(--tx-1);
|
||
font-family: var(--ff-body);
|
||
font-size: 14px; line-height: 1.55;
|
||
min-height: 100vh; overflow-x: hidden;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
body::before{
|
||
content:""; position: fixed; inset: 0;
|
||
background-image:
|
||
repeating-linear-gradient(0deg, rgba(255,255,255,0.012) 0 1px, transparent 1px 3px),
|
||
repeating-linear-gradient(90deg, rgba(255,255,255,0.012) 0 1px, transparent 1px 3px);
|
||
pointer-events: none; z-index: 0;
|
||
}
|
||
main, header, footer, nav, section{ position: relative; z-index: 1; }
|
||
|
||
a{ color: inherit; text-decoration: none; }
|
||
button{ font: inherit; color: inherit; cursor: pointer; background: none; border: 0; }
|
||
|
||
/* =============== HEXA-PIVOT XNAV =============== */
|
||
.xnav{
|
||
display: flex; align-items: center; gap: 4px;
|
||
padding: 14px 28px;
|
||
background: linear-gradient(180deg, rgba(10,14,26,0.95), rgba(10,14,26,0.7));
|
||
border-bottom: 1px solid var(--bd-hair);
|
||
backdrop-filter: blur(18px);
|
||
position: sticky; top: 0; z-index: 50;
|
||
font-family: var(--ff-mono);
|
||
font-size: 11px; letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
overflow-x: auto; white-space: nowrap;
|
||
}
|
||
.xnav a{
|
||
padding: 8px 14px; border-radius: 999px;
|
||
border: 1px solid var(--bd-soft);
|
||
color: var(--tx-3);
|
||
transition: all .25s var(--ease);
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
}
|
||
.xnav a:hover{ color: var(--tx-1); border-color: var(--bd-mid); background: var(--bg-glass); }
|
||
.xnav a.current{
|
||
color: var(--tx-1); border-color: transparent;
|
||
background: linear-gradient(135deg, var(--p-wevia-1), var(--p-product-1));
|
||
box-shadow: 0 0 0 1px var(--bd-mid), 0 8px 24px -8px rgba(124,58,237,0.5);
|
||
}
|
||
.xnav .sep{ color: var(--tx-dim); font-size: 10px; }
|
||
|
||
/* =============== HERO =============== */
|
||
.hero{ padding: 48px 32px 32px; max-width: 1600px; margin: 0 auto; }
|
||
.hero-head{
|
||
display: grid; grid-template-columns: 1.2fr auto;
|
||
gap: 24px; align-items: end; margin-bottom: 36px;
|
||
}
|
||
.eyebrow{
|
||
font-family: var(--ff-mono);
|
||
font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
|
||
color: var(--tx-3);
|
||
display: inline-flex; align-items: center; gap: 10px;
|
||
margin-bottom: 18px;
|
||
}
|
||
.eyebrow .dot{
|
||
width: 6px; height: 6px; border-radius: 50%;
|
||
background: var(--good);
|
||
box-shadow: 0 0 0 4px rgba(52,211,153,0.15), 0 0 14px var(--good);
|
||
animation: pulse 2.2s var(--ease) infinite;
|
||
}
|
||
@keyframes pulse{ 50%{ opacity: .4; transform: scale(.85); } }
|
||
|
||
.hero h1{
|
||
font-family: var(--ff-display); font-weight: 500;
|
||
font-size: clamp(40px, 5.4vw, 78px);
|
||
line-height: 0.95; letter-spacing: -0.02em;
|
||
margin: 0 0 14px; color: var(--tx-1);
|
||
}
|
||
.hero h1 em{
|
||
font-style: normal;
|
||
background: linear-gradient(110deg, var(--p-wevia-1) 0%, var(--p-product-1) 45%, var(--p-biz-1) 80%);
|
||
-webkit-background-clip: text; background-clip: text; color: transparent;
|
||
}
|
||
.hero-sub{ font-size: 16px; color: var(--tx-2); max-width: 720px; line-height: 1.6; }
|
||
.hero-sub strong{ color: var(--tx-1); font-weight: 600; }
|
||
.hero-meta{
|
||
display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
|
||
font-family: var(--ff-mono);
|
||
font-size: 11px; color: var(--tx-3);
|
||
}
|
||
.hero-meta .ts{ color: var(--tx-4); }
|
||
.hero-meta .ver{
|
||
padding: 4px 10px; border: 1px solid var(--bd-mid);
|
||
border-radius: 4px; color: var(--tx-1);
|
||
background: linear-gradient(90deg, rgba(124,58,237,0.15), rgba(6,182,212,0.15));
|
||
}
|
||
|
||
/* =============== PILLAR HERO (4 cards) =============== */
|
||
.pillars-hero{
|
||
display: grid; grid-template-columns: repeat(4, 1fr);
|
||
gap: 14px; margin-top: 14px;
|
||
}
|
||
.phero{
|
||
position: relative; padding: 22px 20px 20px;
|
||
border-radius: var(--r-lg);
|
||
background: linear-gradient(180deg, var(--bg-glass), rgba(14,20,36,0.25));
|
||
border: 1px solid var(--bd-soft);
|
||
backdrop-filter: blur(14px);
|
||
overflow: hidden;
|
||
transition: transform .35s var(--ease);
|
||
}
|
||
.phero:hover{ transform: translateY(-2px); }
|
||
.phero::before{
|
||
content:""; position: absolute; inset: -1px; border-radius: inherit;
|
||
padding: 1px;
|
||
background: linear-gradient(135deg, var(--pc-1), var(--pc-2));
|
||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||
-webkit-mask-composite: xor; mask-composite: exclude;
|
||
opacity: .45;
|
||
}
|
||
.phero[data-pillar="wevia"]{ --pc-1: var(--p-wevia-1); --pc-2: var(--p-wevia-2); }
|
||
.phero[data-pillar="product"]{ --pc-1: var(--p-product-1); --pc-2: var(--p-product-2); }
|
||
.phero[data-pillar="biz"]{ --pc-1: var(--p-biz-1); --pc-2: var(--p-biz-2); }
|
||
.phero[data-pillar="infra"]{ --pc-1: var(--p-infra-1); --pc-2: var(--p-infra-2); }
|
||
|
||
.phero-tag{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
|
||
color: var(--tx-3);
|
||
margin-bottom: 6px;
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
}
|
||
.phero-tag::before{
|
||
content:""; width: 7px; height: 7px; border-radius: 2px;
|
||
background: linear-gradient(135deg, var(--pc-1), var(--pc-2));
|
||
}
|
||
.phero h3{
|
||
font-family: var(--ff-display); font-weight: 500;
|
||
font-size: 18px; letter-spacing: -0.01em;
|
||
margin: 0 0 12px; color: var(--tx-1);
|
||
line-height: 1.2;
|
||
}
|
||
.phero-score{
|
||
display: flex; align-items: baseline; gap: 6px;
|
||
margin-bottom: 12px;
|
||
}
|
||
.phero-score .v{
|
||
font-family: var(--ff-mono); font-weight: 700;
|
||
font-size: 34px; line-height: 1;
|
||
background: linear-gradient(110deg, var(--pc-1), var(--pc-2));
|
||
-webkit-background-clip: text; background-clip: text; color: transparent;
|
||
}
|
||
.phero-score .u{ font-family: var(--ff-mono); font-size: 14px; color: var(--tx-3); }
|
||
.phero-score .d{ margin-left: auto; font-family: var(--ff-mono); font-size: 11px; color: var(--good); }
|
||
.phero-score .d.down{ color: var(--bad); }
|
||
.phero-dots{
|
||
display: flex; gap: 5px;
|
||
font-family: var(--ff-mono); font-size: 10px; color: var(--tx-3);
|
||
margin-top: 10px;
|
||
}
|
||
.phero-dots span{
|
||
flex: 1; text-align: center; padding: 4px;
|
||
background: rgba(5,7,14,0.5);
|
||
border: 1px solid var(--bd-hair);
|
||
border-radius: 4px;
|
||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||
}
|
||
|
||
/* =============== LEVEL GAUGES =============== */
|
||
.gauges-sep{
|
||
margin: 40px 0 18px;
|
||
display: flex; align-items: center; gap: 16px;
|
||
}
|
||
.gauges-sep-line{ flex: 1; height: 1px; background: var(--bd-hair); }
|
||
.gauges-sep-txt{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
|
||
color: var(--tx-3);
|
||
}
|
||
|
||
.gauges{
|
||
display: grid; grid-template-columns: repeat(4, 1fr);
|
||
gap: 14px;
|
||
}
|
||
.gauge-card{
|
||
position: relative; padding: 20px 18px 18px;
|
||
border-radius: var(--r-lg);
|
||
background: linear-gradient(180deg, var(--bg-glass), rgba(14,20,36,0.3));
|
||
border: 1px solid var(--bd-soft);
|
||
backdrop-filter: blur(14px);
|
||
overflow: hidden;
|
||
transition: transform .35s var(--ease);
|
||
}
|
||
.gauge-card::before{
|
||
content:""; position: absolute; inset: -1px; border-radius: inherit;
|
||
padding: 1px;
|
||
background: linear-gradient(135deg, var(--g-c1), var(--g-c2));
|
||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||
-webkit-mask-composite: xor; mask-composite: exclude;
|
||
opacity: .35;
|
||
transition: opacity .35s var(--ease);
|
||
}
|
||
.gauge-card:hover{ transform: translateY(-2px); }
|
||
.gauge-card:hover::before{ opacity: .8; }
|
||
.gauge-card[data-level="strat"]{ --g-c1: var(--strat-1); --g-c2: var(--strat-2); }
|
||
.gauge-card[data-level="tact"]{ --g-c1: var(--tact-1); --g-c2: var(--tact-2); }
|
||
.gauge-card[data-level="op"]{ --g-c1: var(--op-1); --g-c2: var(--op-2); }
|
||
.gauge-card[data-level="infra"]{ --g-c1: var(--infra-1); --g-c2: var(--infra-2); }
|
||
|
||
.gauge-head{ display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
|
||
.gauge-label{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
|
||
color: var(--tx-3);
|
||
}
|
||
.gauge-chip{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.1em;
|
||
padding: 3px 8px; border-radius: 4px;
|
||
background: var(--bg-void); color: var(--g-c1);
|
||
border: 1px solid var(--bd-soft);
|
||
}
|
||
.gauge-body{ display: grid; grid-template-columns: 96px 1fr; gap: 12px; align-items: center; }
|
||
.gauge-body svg{ display: block; }
|
||
.gauge-stats .val{
|
||
font-family: var(--ff-mono);
|
||
font-size: 24px; font-weight: 600;
|
||
color: var(--tx-1); line-height: 1; margin-bottom: 4px;
|
||
}
|
||
.gauge-stats .val small{ font-size: 13px; color: var(--tx-3); margin-left: 3px; font-weight: 500; }
|
||
.gauge-stats .sub{ font-size: 11px; color: var(--tx-3); line-height: 1.4; }
|
||
.gauge-trend{
|
||
margin-top: 10px; display: flex; align-items: center; gap: 8px;
|
||
font-family: var(--ff-mono); font-size: 11px; color: var(--tx-3);
|
||
}
|
||
.gauge-trend .delta{ color: var(--g-c1); font-weight: 600; }
|
||
|
||
/* =============== TICKER =============== */
|
||
.ticker{
|
||
margin: 24px 0 0; padding: 14px 20px;
|
||
border-radius: var(--r-md);
|
||
background: linear-gradient(90deg, rgba(14,20,36,0.7), rgba(14,20,36,0.3));
|
||
border: 1px solid var(--bd-hair);
|
||
display: grid; grid-template-columns: auto 1fr auto;
|
||
align-items: center; gap: 20px;
|
||
font-family: var(--ff-mono); font-size: 12px; color: var(--tx-2);
|
||
overflow: hidden;
|
||
}
|
||
.ticker-label{
|
||
color: var(--tx-3); letter-spacing: 0.18em; text-transform: uppercase;
|
||
font-size: 10px;
|
||
display: inline-flex; align-items: center; gap: 8px;
|
||
}
|
||
.ticker-label .dot{
|
||
width: 6px; height: 6px; border-radius: 50%;
|
||
background: var(--good);
|
||
box-shadow: 0 0 0 3px rgba(52,211,153,0.2);
|
||
animation: pulse 2s var(--ease) infinite;
|
||
}
|
||
.ticker-stream{
|
||
display: flex; gap: 28px; overflow: hidden;
|
||
mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
|
||
}
|
||
.ticker-stream .item{ white-space: nowrap; }
|
||
.ticker-stream .item .k{ color: var(--tx-4); margin-right: 6px; }
|
||
.ticker-stream .item .up{ color: var(--good); }
|
||
.ticker-stream .item .down{ color: var(--bad); }
|
||
.ticker-cta{
|
||
font-size: 11px; color: var(--tx-3);
|
||
padding: 6px 12px;
|
||
border: 1px solid var(--bd-soft); border-radius: 999px;
|
||
transition: all .2s var(--ease);
|
||
}
|
||
.ticker-cta:hover{ color: var(--tx-1); border-color: var(--bd-mid); background: var(--bg-glass); }
|
||
|
||
/* =============== SECTION HEADS =============== */
|
||
.section{ max-width: 1600px; margin: 0 auto; padding: 48px 32px 0; }
|
||
.section-head{
|
||
display: flex; align-items: flex-end; justify-content: space-between;
|
||
gap: 20px; margin-bottom: 24px; padding-bottom: 16px;
|
||
border-bottom: 1px solid var(--bd-hair);
|
||
}
|
||
.section-head h2{
|
||
font-family: var(--ff-display); font-weight: 400;
|
||
font-size: clamp(22px, 2.4vw, 32px); letter-spacing: -0.01em;
|
||
margin: 0; color: var(--tx-1);
|
||
}
|
||
.section-head .tag{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
|
||
color: var(--tx-3); margin-bottom: 6px;
|
||
}
|
||
.section-head p{ color: var(--tx-3); font-size: 13px; margin: 4px 0 0; max-width: 620px; }
|
||
|
||
/* =============== PILLAR GROUP (for matrix + cards) =============== */
|
||
.pgroup{ margin-bottom: 24px; }
|
||
.pgroup-head{
|
||
display: flex; align-items: center; gap: 14px;
|
||
margin-bottom: 14px;
|
||
padding: 10px 14px;
|
||
border-radius: var(--r-sm);
|
||
background: linear-gradient(90deg, var(--pg-bg), transparent 60%);
|
||
border-left: 3px solid var(--pg-c1);
|
||
}
|
||
.pgroup[data-pillar="wevia"]{ --pg-c1: var(--p-wevia-1); --pg-c2: var(--p-wevia-2); --pg-bg: rgba(124,58,237,0.10); }
|
||
.pgroup[data-pillar="product"]{ --pg-c1: var(--p-product-1); --pg-c2: var(--p-product-2); --pg-bg: rgba(6,182,212,0.10); }
|
||
.pgroup[data-pillar="biz"]{ --pg-c1: var(--p-biz-1); --pg-c2: var(--p-biz-2); --pg-bg: rgba(245,158,11,0.10); }
|
||
.pgroup[data-pillar="infra"]{ --pg-c1: var(--p-infra-1); --pg-c2: var(--p-infra-2); --pg-bg: rgba(100,116,139,0.12); }
|
||
|
||
.pgroup-head .num{
|
||
font-family: var(--ff-display);
|
||
font-weight: 500; font-size: 14px;
|
||
color: var(--pg-c1);
|
||
min-width: 24px;
|
||
}
|
||
.pgroup-head .lbl{
|
||
font-family: var(--ff-display);
|
||
font-weight: 500; font-size: 16px;
|
||
color: var(--tx-1);
|
||
letter-spacing: -0.01em;
|
||
}
|
||
.pgroup-head .desc{
|
||
font-size: 12px; color: var(--tx-3);
|
||
margin-left: 10px;
|
||
font-family: var(--ff-body);
|
||
}
|
||
.pgroup-head .score{
|
||
margin-left: auto;
|
||
font-family: var(--ff-mono);
|
||
font-size: 11px; color: var(--tx-3);
|
||
display: inline-flex; align-items: center; gap: 10px;
|
||
}
|
||
.pgroup-head .score b{
|
||
color: var(--tx-1); font-weight: 600;
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* =============== MATRIX HEATMAP =============== */
|
||
.matrix-wrap{
|
||
border-radius: var(--r-lg); padding: 24px;
|
||
background: linear-gradient(180deg, var(--bg-glass), rgba(14,20,36,0.2));
|
||
border: 1px solid var(--bd-hair);
|
||
backdrop-filter: blur(14px);
|
||
overflow-x: auto;
|
||
}
|
||
.matrix{
|
||
display: grid;
|
||
grid-template-columns: 220px repeat(4, 1fr);
|
||
gap: 6px;
|
||
min-width: 820px;
|
||
}
|
||
.mx-top{
|
||
display: contents;
|
||
}
|
||
.mx-top .mx-head{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
|
||
color: var(--tx-3);
|
||
padding: 10px 6px;
|
||
border-bottom: 1px solid var(--bd-hair);
|
||
display: flex; align-items: center; gap: 8px;
|
||
}
|
||
.mx-top .mx-head:first-child{ color: var(--tx-1); }
|
||
.mx-top .mx-head .lv-dot{ width: 7px; height: 7px; border-radius: 2px; }
|
||
.mx-top .mx-head[data-level="strat"] .lv-dot{ background: var(--strat-1); }
|
||
.mx-top .mx-head[data-level="tact"] .lv-dot{ background: var(--tact-1); }
|
||
.mx-top .mx-head[data-level="op"] .lv-dot{ background: var(--op-1); }
|
||
.mx-top .mx-head[data-level="infra"] .lv-dot{ background: var(--infra-1); }
|
||
|
||
.mx-pillar-row{
|
||
grid-column: 1 / -1;
|
||
display: flex; align-items: center; gap: 10px;
|
||
padding: 14px 10px 6px;
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
|
||
color: var(--tx-3);
|
||
border-top: 1px solid var(--bd-hair);
|
||
margin-top: 4px;
|
||
}
|
||
.mx-pillar-row[data-pillar="wevia"]{ color: var(--p-wevia-1); }
|
||
.mx-pillar-row[data-pillar="product"]{ color: var(--p-product-1); }
|
||
.mx-pillar-row[data-pillar="biz"]{ color: var(--p-biz-1); }
|
||
.mx-pillar-row[data-pillar="infra"]{ color: #94a3b8; }
|
||
.mx-pillar-row .line{
|
||
flex: 1; height: 1px;
|
||
background: linear-gradient(90deg, currentColor, transparent);
|
||
opacity: 0.4;
|
||
}
|
||
|
||
.dept-name{
|
||
font-family: var(--ff-display);
|
||
font-weight: 500; font-size: 13px;
|
||
padding: 14px 6px;
|
||
color: var(--tx-2);
|
||
display: flex; flex-direction: column; gap: 3px;
|
||
}
|
||
.dept-name .system-badge{
|
||
font-family: var(--ff-mono);
|
||
font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase;
|
||
padding: 2px 6px;
|
||
border-radius: 3px;
|
||
width: fit-content;
|
||
border: 1px solid var(--bd-hair);
|
||
}
|
||
.dept-name .system-badge[data-tax="wevia"] { color: var(--tax-wevia); border-color: rgba(168,85,247,0.3); background: rgba(168,85,247,0.08); }
|
||
.dept-name .system-badge[data-tax="native"] { color: var(--tax-native); border-color: rgba(20,184,166,0.3); background: rgba(20,184,166,0.08); }
|
||
.dept-name .system-badge[data-tax="sap"] { color: var(--tax-sap); border-color: rgba(59,130,246,0.3); background: rgba(59,130,246,0.08); }
|
||
.dept-name .system-badge[data-tax="hybrid"] { color: var(--tax-hybrid); border-color: rgba(245,158,11,0.3); background: rgba(245,158,11,0.08); }
|
||
.dept-name .system-badge[data-tax="partner"]{ color: var(--tax-partner); border-color: rgba(236,72,153,0.3); background: rgba(236,72,153,0.08); }
|
||
.dept-name .system-badge[data-tax="infra"] { color: var(--tax-infra); border-color: rgba(100,116,139,0.35); background: rgba(100,116,139,0.10); }
|
||
|
||
.cell{
|
||
position: relative;
|
||
padding: 12px 10px; border-radius: 8px;
|
||
background: var(--bg-base);
|
||
border: 1px solid var(--bd-hair);
|
||
display: flex; flex-direction: column; gap: 6px;
|
||
cursor: pointer;
|
||
transition: all .25s var(--ease);
|
||
min-height: 72px;
|
||
}
|
||
.cell:hover{
|
||
transform: translateY(-2px);
|
||
border-color: var(--bd-mid);
|
||
z-index: 2;
|
||
box-shadow: 0 10px 30px -10px rgba(0,0,0,0.6);
|
||
}
|
||
.cell .kpi{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; color: var(--tx-4);
|
||
letter-spacing: 0.06em; text-transform: uppercase;
|
||
}
|
||
.cell .val{
|
||
font-family: var(--ff-mono);
|
||
font-size: 16px; font-weight: 600;
|
||
color: var(--tx-1); line-height: 1;
|
||
}
|
||
.cell .val small{ font-size: 11px; color: var(--tx-3); font-weight: 500; margin-left: 3px; }
|
||
.cell .delta{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px;
|
||
display: inline-flex; align-items: center; gap: 4px;
|
||
margin-top: auto;
|
||
}
|
||
.cell .delta.up{ color: var(--good); }
|
||
.cell .delta.down{ color: var(--bad); }
|
||
.cell .delta.flat{ color: var(--neutral); }
|
||
.cell .heat{
|
||
position: absolute; inset: 0;
|
||
border-radius: inherit;
|
||
opacity: 0.10; pointer-events: none;
|
||
transition: opacity .25s var(--ease);
|
||
}
|
||
.cell:hover .heat{ opacity: 0.20; }
|
||
.cell[data-level="strat"] .heat{ background: linear-gradient(135deg, var(--strat-1), var(--strat-2)); }
|
||
.cell[data-level="tact"] .heat{ background: linear-gradient(135deg, var(--tact-1), var(--tact-2)); }
|
||
.cell[data-level="op"] .heat{ background: linear-gradient(135deg, var(--op-1), var(--op-2)); }
|
||
.cell[data-level="infra"] .heat{ background: linear-gradient(135deg, var(--infra-1), var(--infra-2)); }
|
||
|
||
.cell .src-badge{
|
||
position: absolute; top: 6px; right: 7px;
|
||
font-family: var(--ff-mono);
|
||
font-size: 8px; letter-spacing: 0.08em; text-transform: uppercase;
|
||
padding: 2px 5px; border-radius: 3px;
|
||
background: rgba(0,0,0,0.4);
|
||
border: 1px solid var(--bd-hair);
|
||
color: var(--tx-3);
|
||
}
|
||
.cell .src-badge[data-src="live"]{ color: var(--good); border-color: rgba(52,211,153,0.3); }
|
||
.cell .src-badge[data-src="trend"]{ color: var(--tact-1); border-color: rgba(34,211,238,0.3); }
|
||
.cell .src-badge[data-src="forecast"]{ color: var(--strat-1); border-color: rgba(217,70,239,0.3); }
|
||
.cell .src-badge[data-src="todo"]{ color: var(--warn); border-color: rgba(251,191,36,0.3); }
|
||
|
||
/* =============== DEPT CARDS =============== */
|
||
.deptgrid{
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
|
||
gap: 14px;
|
||
margin-bottom: 8px;
|
||
}
|
||
.dcard{
|
||
padding: 18px;
|
||
border-radius: var(--r-md);
|
||
background: linear-gradient(180deg, var(--bg-glass), rgba(14,20,36,0.3));
|
||
border: 1px solid var(--bd-hair);
|
||
backdrop-filter: blur(12px);
|
||
display: flex; flex-direction: column; gap: 12px;
|
||
transition: all .3s var(--ease);
|
||
position: relative; overflow: hidden;
|
||
}
|
||
.dcard:hover{
|
||
transform: translateY(-3px);
|
||
border-color: var(--bd-mid);
|
||
}
|
||
.dcard::before{
|
||
content:"";
|
||
position: absolute; top: 0; left: 0; right: 0; height: 2px;
|
||
background: linear-gradient(90deg, var(--strat-1), var(--tact-1), var(--op-1), var(--infra-1));
|
||
opacity: 0.6;
|
||
}
|
||
.dcard-head{
|
||
display: flex; align-items: center; justify-content: space-between; gap: 10px;
|
||
}
|
||
.dcard-head .dname{
|
||
font-family: var(--ff-display); font-weight: 500;
|
||
font-size: 15px; color: var(--tx-1);
|
||
display: flex; flex-direction: column; gap: 4px;
|
||
min-width: 0;
|
||
}
|
||
.dcard-head .dname .nm{
|
||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||
}
|
||
.dcard-head .dname .system-badge{
|
||
font-family: var(--ff-mono);
|
||
font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase;
|
||
padding: 2px 6px; border-radius: 3px;
|
||
width: fit-content;
|
||
}
|
||
.dcard-head .dname .system-badge[data-tax="wevia"] { color: var(--tax-wevia); border: 1px solid rgba(168,85,247,0.3); background: rgba(168,85,247,0.08); }
|
||
.dcard-head .dname .system-badge[data-tax="native"] { color: var(--tax-native); border: 1px solid rgba(20,184,166,0.3); background: rgba(20,184,166,0.08); }
|
||
.dcard-head .dname .system-badge[data-tax="sap"] { color: var(--tax-sap); border: 1px solid rgba(59,130,246,0.3); background: rgba(59,130,246,0.08); }
|
||
.dcard-head .dname .system-badge[data-tax="hybrid"] { color: var(--tax-hybrid); border: 1px solid rgba(245,158,11,0.3); background: rgba(245,158,11,0.08); }
|
||
.dcard-head .dname .system-badge[data-tax="partner"]{ color: var(--tax-partner); border: 1px solid rgba(236,72,153,0.3); background: rgba(236,72,153,0.08); }
|
||
.dcard-head .dname .system-badge[data-tax="infra"] { color: var(--tax-infra); border: 1px solid rgba(100,116,139,0.35); background: rgba(100,116,139,0.10); }
|
||
|
||
.dcard-head .status{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.1em;
|
||
padding: 3px 8px; border-radius: 999px;
|
||
background: rgba(52,211,153,0.1); color: var(--good);
|
||
border: 1px solid rgba(52,211,153,0.2);
|
||
white-space: nowrap; flex-shrink: 0;
|
||
}
|
||
.dcard-head .status.warn{ background: rgba(251,191,36,0.1); color: var(--warn); border-color: rgba(251,191,36,0.2); }
|
||
.dcard-head .status.bad{ background: rgba(248,113,113,0.1); color: var(--bad); border-color: rgba(248,113,113,0.2); }
|
||
|
||
.dcard-spark{ height: 52px; position: relative; }
|
||
.dcard-spark svg{ width: 100%; height: 100%; display: block; }
|
||
|
||
.dcard-preds{
|
||
display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px;
|
||
}
|
||
.pred{
|
||
padding: 10px; border-radius: 8px;
|
||
background: rgba(5,7,14,0.5);
|
||
border: 1px solid var(--bd-hair);
|
||
display: flex; flex-direction: column; gap: 4px;
|
||
}
|
||
.pred-head{
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
font-family: var(--ff-mono);
|
||
font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase;
|
||
}
|
||
.pred-head .lv{ display: inline-flex; align-items: center; gap: 5px; color: var(--tx-3); }
|
||
.pred-head .lv .d{ width: 6px; height: 6px; border-radius: 2px; }
|
||
.pred[data-level="strat"] .lv .d{ background: var(--strat-1); }
|
||
.pred[data-level="tact"] .lv .d{ background: var(--tact-1); }
|
||
.pred[data-level="op"] .lv .d{ background: var(--op-1); }
|
||
.pred[data-level="infra"] .lv .d{ background: var(--infra-1); }
|
||
.pred-head .src{ font-size: 8px; color: var(--tx-4); }
|
||
.pred-head .src.live{ color: var(--good); }
|
||
.pred-head .src.trend{ color: var(--tact-1); }
|
||
.pred-head .src.forecast{ color: var(--strat-1); }
|
||
.pred-head .src.todo{ color: var(--warn); }
|
||
.pred-val{
|
||
font-family: var(--ff-mono);
|
||
font-size: 16px; font-weight: 600;
|
||
color: var(--tx-1); line-height: 1;
|
||
}
|
||
.pred-val small{ font-size: 10px; color: var(--tx-3); font-weight: 500; margin-left: 3px; }
|
||
.pred-kpi{ font-size: 10px; color: var(--tx-3); }
|
||
.pred-bullet{
|
||
margin-top: 4px; height: 4px; border-radius: 2px;
|
||
background: var(--bg-void);
|
||
position: relative; overflow: hidden;
|
||
}
|
||
.pred-bullet .fill{
|
||
position: absolute; left: 0; top: 0; bottom: 0;
|
||
border-radius: 2px;
|
||
}
|
||
.pred[data-level="strat"] .pred-bullet .fill{ background: linear-gradient(90deg, var(--strat-1), var(--strat-2)); }
|
||
.pred[data-level="tact"] .pred-bullet .fill{ background: linear-gradient(90deg, var(--tact-1), var(--tact-2)); }
|
||
.pred[data-level="op"] .pred-bullet .fill{ background: linear-gradient(90deg, var(--op-1), var(--op-2)); }
|
||
.pred[data-level="infra"] .pred-bullet .fill{ background: linear-gradient(90deg, var(--infra-1), var(--infra-2)); }
|
||
.pred-bullet .target{
|
||
position: absolute; top: -2px; bottom: -2px; width: 2px;
|
||
background: var(--tx-1); opacity: 0.5;
|
||
}
|
||
|
||
/* =============== LEVEL BANDS =============== */
|
||
.bands{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
|
||
.band{
|
||
padding: 22px; border-radius: var(--r-md);
|
||
background: linear-gradient(180deg, var(--bg-glass), rgba(14,20,36,0.2));
|
||
border: 1px solid var(--bd-hair);
|
||
position: relative; overflow: hidden;
|
||
}
|
||
.band::after{
|
||
content:""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
|
||
background: linear-gradient(90deg, var(--b-c1), var(--b-c2));
|
||
}
|
||
.band[data-level="strat"]{ --b-c1: var(--strat-1); --b-c2: var(--strat-2); }
|
||
.band[data-level="tact"]{ --b-c1: var(--tact-1); --b-c2: var(--tact-2); }
|
||
.band[data-level="op"]{ --b-c1: var(--op-1); --b-c2: var(--op-2); }
|
||
.band[data-level="infra"]{ --b-c1: var(--infra-1); --b-c2: var(--infra-2); }
|
||
|
||
.band-name{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
|
||
color: var(--tx-3); margin-bottom: 6px;
|
||
}
|
||
.band-title{
|
||
font-family: var(--ff-display); font-weight: 500;
|
||
font-size: 18px; color: var(--tx-1); margin-bottom: 14px;
|
||
}
|
||
.band-metric{
|
||
font-family: var(--ff-mono);
|
||
font-size: 32px; font-weight: 600; line-height: 1;
|
||
background: linear-gradient(110deg, var(--b-c1), var(--b-c2));
|
||
-webkit-background-clip: text; background-clip: text; color: transparent;
|
||
margin-bottom: 10px;
|
||
}
|
||
.band-chart{ height: 70px; margin: 10px 0; }
|
||
.band-chart svg{ width: 100%; height: 100%; display: block; }
|
||
.band-bullets{ display: flex; flex-direction: column; gap: 6px; font-size: 12px; color: var(--tx-2); padding: 0; margin: 0; }
|
||
.band-bullets li{ display: flex; align-items: flex-start; gap: 8px; list-style: none; }
|
||
.band-bullets li::before{
|
||
content: ""; width: 6px; height: 6px; border-radius: 2px;
|
||
background: linear-gradient(135deg, var(--b-c1), var(--b-c2));
|
||
margin-top: 6px; flex-shrink: 0;
|
||
}
|
||
|
||
/* =============== SOURCES =============== */
|
||
.sources-card{
|
||
margin-top: 28px; padding: 24px;
|
||
border-radius: var(--r-md);
|
||
background: linear-gradient(180deg, rgba(14,20,36,0.4), rgba(5,7,14,0.3));
|
||
border: 1px solid var(--bd-hair);
|
||
display: grid; grid-template-columns: 1.5fr 3fr;
|
||
gap: 32px; align-items: start;
|
||
}
|
||
.sources-card h3{
|
||
font-family: var(--ff-display); font-weight: 500;
|
||
font-size: 18px; margin: 0 0 8px; color: var(--tx-1);
|
||
}
|
||
.sources-card p{ font-size: 13px; color: var(--tx-3); margin: 0 0 16px; line-height: 1.6; }
|
||
.src-pills{ display: flex; flex-wrap: wrap; gap: 8px; }
|
||
.src-pill{
|
||
padding: 6px 12px; border-radius: 999px;
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.08em;
|
||
background: var(--bg-base);
|
||
border: 1px solid var(--bd-soft);
|
||
color: var(--tx-2);
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
}
|
||
.src-pill.live{ color: var(--good); border-color: rgba(52,211,153,0.3); }
|
||
.src-pill.trend{ color: var(--tact-1); border-color: rgba(34,211,238,0.3); }
|
||
.src-pill.forecast{ color: var(--strat-1); border-color: rgba(217,70,239,0.3); }
|
||
.src-pill.todo{ color: var(--warn); border-color: rgba(251,191,36,0.3); }
|
||
.src-pill .count{ color: var(--tx-1); font-weight: 600; }
|
||
|
||
.tax-legend{
|
||
display: flex; flex-wrap: wrap; gap: 10px;
|
||
margin-top: 16px; padding-top: 16px;
|
||
border-top: 1px dashed var(--bd-hair);
|
||
}
|
||
.tax-legend .tx-pill{
|
||
padding: 5px 10px; border-radius: 4px;
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.08em;
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
}
|
||
.tax-legend .tx-pill .sw{ width: 10px; height: 10px; border-radius: 2px; }
|
||
.tax-legend .tx-pill[data-tax="wevia"] { color: var(--tax-wevia); background: rgba(168,85,247,0.08); border: 1px solid rgba(168,85,247,0.3); }
|
||
.tax-legend .tx-pill[data-tax="native"] { color: var(--tax-native); background: rgba(20,184,166,0.08); border: 1px solid rgba(20,184,166,0.3); }
|
||
.tax-legend .tx-pill[data-tax="sap"] { color: var(--tax-sap); background: rgba(59,130,246,0.08); border: 1px solid rgba(59,130,246,0.3); }
|
||
.tax-legend .tx-pill[data-tax="hybrid"] { color: var(--tax-hybrid); background: rgba(245,158,11,0.08); border: 1px solid rgba(245,158,11,0.3); }
|
||
.tax-legend .tx-pill[data-tax="partner"]{ color: var(--tax-partner); background: rgba(236,72,153,0.08); border: 1px solid rgba(236,72,153,0.3); }
|
||
.tax-legend .tx-pill[data-tax="infra"] { color: var(--tax-infra); background: rgba(100,116,139,0.10); border: 1px solid rgba(100,116,139,0.35); }
|
||
.tax-legend .tx-pill .sw[data-tax="wevia"] { background: var(--tax-wevia); }
|
||
.tax-legend .tx-pill .sw[data-tax="native"] { background: var(--tax-native); }
|
||
.tax-legend .tx-pill .sw[data-tax="sap"] { background: var(--tax-sap); }
|
||
.tax-legend .tx-pill .sw[data-tax="hybrid"] { background: var(--tax-hybrid); }
|
||
.tax-legend .tx-pill .sw[data-tax="partner"]{ background: var(--tax-partner); }
|
||
.tax-legend .tx-pill .sw[data-tax="infra"] { background: var(--tax-infra); }
|
||
.tax-legend .tx-pill .count{ color: var(--tx-1); font-weight: 600; }
|
||
|
||
/* =============== MIROFISH CTA =============== */
|
||
.engine-card{
|
||
margin-top: 28px; padding: 32px;
|
||
border-radius: var(--r-lg);
|
||
background:
|
||
radial-gradient(600px 300px at 100% 0%, rgba(168,85,247,0.12), transparent 60%),
|
||
radial-gradient(500px 280px at 0% 100%, rgba(34,211,238,0.1), transparent 55%),
|
||
linear-gradient(180deg, var(--bg-glass-strong), var(--bg-base));
|
||
border: 1px solid var(--bd-soft);
|
||
display: grid; grid-template-columns: 1fr auto; gap: 24px; align-items: center;
|
||
}
|
||
.engine-card .tag{
|
||
font-family: var(--ff-mono);
|
||
font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
|
||
color: var(--tx-3);
|
||
margin-bottom: 8px;
|
||
display: inline-flex; align-items: center; gap: 8px;
|
||
}
|
||
.engine-card .tag::before{
|
||
content:""; width: 5px; height: 5px; border-radius: 50%;
|
||
background: var(--strat-1); box-shadow: 0 0 10px var(--strat-1);
|
||
}
|
||
.engine-card h3{
|
||
font-family: var(--ff-display); font-weight: 500;
|
||
font-size: 24px; margin: 0 0 10px; color: var(--tx-1);
|
||
}
|
||
.engine-card p{ color: var(--tx-3); font-size: 13px; margin: 0; max-width: 680px; line-height: 1.6; }
|
||
.engine-cta{
|
||
display: inline-flex; align-items: center; gap: 10px;
|
||
padding: 14px 22px; border-radius: 999px;
|
||
background: linear-gradient(135deg, var(--strat-1), var(--tact-2));
|
||
color: white;
|
||
font-family: var(--ff-mono);
|
||
font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
|
||
font-weight: 600;
|
||
transition: all .3s var(--ease);
|
||
box-shadow: 0 10px 30px -10px var(--strat-glow);
|
||
white-space: nowrap;
|
||
}
|
||
.engine-cta:hover{ transform: translateY(-2px); box-shadow: 0 14px 36px -10px var(--strat-glow); }
|
||
|
||
/* =============== FOOTER =============== */
|
||
footer.eco{
|
||
margin-top: 60px; padding: 16px 28px;
|
||
border-top: 1px solid var(--bd-hair);
|
||
background: linear-gradient(0deg, rgba(10,14,26,0.9), rgba(10,14,26,0.5));
|
||
backdrop-filter: blur(14px);
|
||
font-family: var(--ff-mono);
|
||
font-size: 11px; color: var(--tx-3);
|
||
display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center;
|
||
gap: 14px;
|
||
}
|
||
footer.eco .items{ display: flex; flex-wrap: wrap; gap: 18px; align-items: center; }
|
||
footer.eco .items span{ display: inline-flex; align-items: center; gap: 6px; }
|
||
footer.eco .items .v{ color: var(--tx-1); font-weight: 600; }
|
||
footer.eco .items .ok{ color: var(--good); }
|
||
footer.eco .sep{ color: var(--tx-dim); }
|
||
footer.eco .truth-link{
|
||
color: var(--tact-1);
|
||
padding: 4px 10px; border: 1px solid rgba(34,211,238,0.2);
|
||
border-radius: 4px; transition: all .2s var(--ease);
|
||
}
|
||
footer.eco .truth-link:hover{ background: rgba(34,211,238,0.08); border-color: rgba(34,211,238,0.5); }
|
||
|
||
/* =============== RESPONSIVE =============== */
|
||
@media (max-width: 1100px){
|
||
.pillars-hero{ grid-template-columns: repeat(2,1fr); }
|
||
.gauges{ grid-template-columns: repeat(2,1fr); }
|
||
.bands{ grid-template-columns: repeat(2,1fr); }
|
||
.sources-card{ grid-template-columns: 1fr; }
|
||
.engine-card{ grid-template-columns: 1fr; }
|
||
.hero-head{ grid-template-columns: 1fr; }
|
||
.hero-meta{ align-items: flex-start; }
|
||
}
|
||
@media (max-width: 640px){
|
||
.hero{ padding: 32px 18px 18px; }
|
||
.section{ padding: 32px 18px 0; }
|
||
.pillars-hero{ grid-template-columns: 1fr; }
|
||
.gauges{ grid-template-columns: 1fr; }
|
||
.bands{ grid-template-columns: 1fr; }
|
||
.deptgrid{ grid-template-columns: 1fr; }
|
||
.xnav{ padding: 12px 16px; }
|
||
}
|
||
|
||
.reveal{ opacity: 0; transform: translateY(12px); animation: reveal .7s var(--ease) forwards; }
|
||
@keyframes reveal{ to{ opacity: 1; transform: none; } }
|
||
.reveal:nth-child(1){ animation-delay: .05s; }
|
||
.reveal:nth-child(2){ animation-delay: .15s; }
|
||
.reveal:nth-child(3){ animation-delay: .25s; }
|
||
.reveal:nth-child(4){ animation-delay: .35s; }
|
||
.reveal:nth-child(5){ animation-delay: .45s; }
|
||
|
||
:focus-visible{ outline: 2px solid var(--tact-1); outline-offset: 3px; border-radius: 6px; }
|
||
</style>
|
||
<!-- DOCTRINE-60-UX-ENRICH direct-inject-20260424-143816 -->
|
||
<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>
|
||
|
||
<nav class="xnav" aria-label="Pivot ecosystem">
|
||
<a href="/weval-technology-platform.html">← WTP</a>
|
||
<span class="sep">/</span>
|
||
<a href="/all-ia-hub.html">All-IA</a>
|
||
<span class="sep">/</span>
|
||
<a href="/weval-arena.html">Arena</a>
|
||
<span class="sep">/</span>
|
||
<a href="/wevia-master.html">WEVIA Master</a>
|
||
<span class="sep">/</span>
|
||
<a href="/wevia-orchestrator.html">Orchestrator</a>
|
||
<span class="sep">/</span>
|
||
<a href="/wevia-unified-hub.html">Truth Hub</a>
|
||
<span class="sep">·</span>
|
||
<a href="#" class="current">WePredict Cockpit</a>
|
||
</nav>
|
||
|
||
<header class="hero">
|
||
<div class="hero-head">
|
||
<div class="reveal">
|
||
<div class="eyebrow"><span class="dot"></span> Couverture WEVAL complète · 4 piliers × 4 domaines · 64 prédictions</div>
|
||
<h1>WePredict <em>Cockpit</em></h1>
|
||
<p class="hero-sub">Plateforme prédictive pour <strong>tout l'écosystème WEVAL</strong> — pas seulement SAP. Source unique <strong>Truth Registry</strong> (906 agents · 1263 intents · 15 providers · 15509 skills). Quatre piliers : <strong>WEVIA</strong> (IA souveraine), <strong>Produits natifs</strong> (WEVADS/Ethica/Paperclip/Arsenal), <strong>Business</strong> (SAP + sales + gouvernance), <strong>Cloud & Infra</strong> (S204/S95/DevOps/Sécurité). Chaque domaine affiche son vrai système — pas de SAP-washing.</p>
|
||
</div>
|
||
<div class="hero-meta reveal">
|
||
<span class="ver">V146 · Truth Registry aligned</span>
|
||
<span>Auto-refresh <strong>30s</strong></span>
|
||
<span class="ts" id="ts-now">—</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 4 PILLAR HERO CARDS -->
|
||
<div class="pillars-hero">
|
||
<article class="phero reveal" data-pillar="wevia">
|
||
<div class="phero-tag">Pilier I · Sovereign AI</div>
|
||
<h3>WEVIA — IA souveraine 0€</h3>
|
||
<div class="phero-score">
|
||
<span class="v">87</span><span class="u">/100</span>
|
||
<span class="d">▲ +3.2pt</span>
|
||
</div>
|
||
<div class="phero-dots">
|
||
<span>Master</span><span>Enterprise</span><span>Arena</span><span>LIFE</span>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="phero reveal" data-pillar="product">
|
||
<div class="phero-tag">Pilier II · Native Products</div>
|
||
<h3>WEVAL — produits propriétaires</h3>
|
||
<div class="phero-score">
|
||
<span class="v">82</span><span class="u">/100</span>
|
||
<span class="d">▲ +2.1pt</span>
|
||
</div>
|
||
<div class="phero-dots">
|
||
<span>WEVADS</span><span>Ethica</span><span>Paperclip</span><span>Arsenal</span>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="phero reveal" data-pillar="biz">
|
||
<div class="phero-tag">Pilier III · Business</div>
|
||
<h3>SAP + Sales + Gouvernance</h3>
|
||
<div class="phero-score">
|
||
<span class="v">79</span><span class="u">/100</span>
|
||
<span class="d">▲ +1.4pt</span>
|
||
</div>
|
||
<div class="phero-dots">
|
||
<span>Finance</span><span>Sales</span><span>Supply</span><span>DG</span>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="phero reveal" data-pillar="infra">
|
||
<div class="phero-tag">Pilier IV · Cloud & Infra</div>
|
||
<h3>Souveraineté technique</h3>
|
||
<div class="phero-score">
|
||
<span class="v">94</span><span class="u">/100</span>
|
||
<span class="d">▲ +0.3pt</span>
|
||
</div>
|
||
<div class="phero-dots">
|
||
<span>S204</span><span>S95</span><span>DevOps</span><span>Sec</span>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
|
||
<!-- 4 LEVEL GAUGES -->
|
||
<div class="gauges-sep">
|
||
<span class="gauges-sep-line"></span>
|
||
<span class="gauges-sep-txt">◆ 4 niveaux décisionnels transverses aux 16 domaines</span>
|
||
<span class="gauges-sep-line"></span>
|
||
</div>
|
||
|
||
<div class="gauges">
|
||
<article class="gauge-card reveal" data-level="strat">
|
||
<div class="gauge-head"><span class="gauge-label">◆ Stratégique</span><span class="gauge-chip">90-180j · Board</span></div>
|
||
<div class="gauge-body">
|
||
<svg viewBox="0 0 96 96" width="96" height="96">
|
||
<defs><linearGradient id="gS" x1="0" x2="1"><stop offset="0%" stop-color="#d946ef"/><stop offset="100%" stop-color="#a855f7"/></linearGradient></defs>
|
||
<circle cx="48" cy="48" r="38" fill="none" stroke="rgba(255,255,255,0.06)" stroke-width="7"/>
|
||
<circle cx="48" cy="48" r="38" fill="none" stroke="url(#gS)" stroke-width="7" stroke-linecap="round" stroke-dasharray="239" stroke-dashoffset="50" transform="rotate(-90 48 48)"/>
|
||
<text x="48" y="52" text-anchor="middle" font-family="JetBrains Mono" font-size="20" font-weight="700" fill="#eef2ff">79</text>
|
||
<text x="48" y="66" text-anchor="middle" font-family="JetBrains Mono" font-size="7" fill="#8591af" letter-spacing="1">CONFIDENCE</text>
|
||
</svg>
|
||
<div class="gauge-stats">
|
||
<div class="val">16<small>/16 dom.</small></div>
|
||
<div class="sub">Board · M&A · ARR · Risk · Roadmap</div>
|
||
</div>
|
||
</div>
|
||
<div class="gauge-trend"><span class="delta">▲ +2.4pt</span><span>horizon 90j</span></div>
|
||
</article>
|
||
|
||
<article class="gauge-card reveal" data-level="tact">
|
||
<div class="gauge-head"><span class="gauge-label">◆ Tactique</span><span class="gauge-chip">30-90j · Mgmt</span></div>
|
||
<div class="gauge-body">
|
||
<svg viewBox="0 0 96 96" width="96" height="96">
|
||
<defs><linearGradient id="gT" x1="0" x2="1"><stop offset="0%" stop-color="#22d3ee"/><stop offset="100%" stop-color="#3b82f6"/></linearGradient></defs>
|
||
<circle cx="48" cy="48" r="38" fill="none" stroke="rgba(255,255,255,0.06)" stroke-width="7"/>
|
||
<circle cx="48" cy="48" r="38" fill="none" stroke="url(#gT)" stroke-width="7" stroke-linecap="round" stroke-dasharray="239" stroke-dashoffset="36" transform="rotate(-90 48 48)"/>
|
||
<text x="48" y="52" text-anchor="middle" font-family="JetBrains Mono" font-size="20" font-weight="700" fill="#eef2ff">85</text>
|
||
<text x="48" y="66" text-anchor="middle" font-family="JetBrains Mono" font-size="7" fill="#8591af" letter-spacing="1">CONFIDENCE</text>
|
||
</svg>
|
||
<div class="gauge-stats">
|
||
<div class="val">16<small>/16 dom.</small></div>
|
||
<div class="sub">OKR · Pipeline · Capacity · Velocity</div>
|
||
</div>
|
||
</div>
|
||
<div class="gauge-trend"><span class="delta">▲ +4.1pt</span><span>horizon 30j</span></div>
|
||
</article>
|
||
|
||
<article class="gauge-card reveal" data-level="op">
|
||
<div class="gauge-head"><span class="gauge-label">◆ Opérationnel</span><span class="gauge-chip">1-7j · Terrain</span></div>
|
||
<div class="gauge-body">
|
||
<svg viewBox="0 0 96 96" width="96" height="96">
|
||
<defs><linearGradient id="gO" x1="0" x2="1"><stop offset="0%" stop-color="#84cc16"/><stop offset="100%" stop-color="#10b981"/></linearGradient></defs>
|
||
<circle cx="48" cy="48" r="38" fill="none" stroke="rgba(255,255,255,0.06)" stroke-width="7"/>
|
||
<circle cx="48" cy="48" r="38" fill="none" stroke="url(#gO)" stroke-width="7" stroke-linecap="round" stroke-dasharray="239" stroke-dashoffset="22" transform="rotate(-90 48 48)"/>
|
||
<text x="48" y="52" text-anchor="middle" font-family="JetBrains Mono" font-size="20" font-weight="700" fill="#eef2ff">91</text>
|
||
<text x="48" y="66" text-anchor="middle" font-family="JetBrains Mono" font-size="7" fill="#8591af" letter-spacing="1">CONFIDENCE</text>
|
||
</svg>
|
||
<div class="gauge-stats">
|
||
<div class="val">16<small>/16 dom.</small></div>
|
||
<div class="sub">SLA · Leads · Incidents · Throughput</div>
|
||
</div>
|
||
</div>
|
||
<div class="gauge-trend"><span class="delta">▲ +1.8pt</span><span>horizon 7j</span></div>
|
||
</article>
|
||
|
||
<article class="gauge-card reveal" data-level="infra">
|
||
<div class="gauge-head"><span class="gauge-label">◆ Infrastructure</span><span class="gauge-chip">Live · Système</span></div>
|
||
<div class="gauge-body">
|
||
<svg viewBox="0 0 96 96" width="96" height="96">
|
||
<defs><linearGradient id="gI" x1="0" x2="1"><stop offset="0%" stop-color="#f59e0b"/><stop offset="100%" stop-color="#ef4444"/></linearGradient></defs>
|
||
<circle cx="48" cy="48" r="38" fill="none" stroke="rgba(255,255,255,0.06)" stroke-width="7"/>
|
||
<circle cx="48" cy="48" r="38" fill="none" stroke="url(#gI)" stroke-width="7" stroke-linecap="round" stroke-dasharray="239" stroke-dashoffset="15" transform="rotate(-90 48 48)"/>
|
||
<text x="48" y="52" text-anchor="middle" font-family="JetBrains Mono" font-size="20" font-weight="700" fill="#eef2ff">94</text>
|
||
<text x="48" y="66" text-anchor="middle" font-family="JetBrains Mono" font-size="7" fill="#8591af" letter-spacing="1">CONFIDENCE</text>
|
||
</svg>
|
||
<div class="gauge-stats">
|
||
<div class="val">16<small>/16 dom.</small></div>
|
||
<div class="sub">CPU · RAM · Disk · Latency · Uptime</div>
|
||
</div>
|
||
</div>
|
||
<div class="gauge-trend"><span class="delta">▲ +0.3pt</span><span>horizon 24h</span></div>
|
||
</article>
|
||
</div>
|
||
|
||
<div class="ticker reveal">
|
||
<span class="ticker-label"><span class="dot"></span> Live signals</span>
|
||
<div class="ticker-stream">
|
||
<span class="item"><span class="k">L99 combined</span> <span class="up">201/201</span></span>
|
||
<span class="item"><span class="k">legacy</span> <span class="up">153/153</span></span>
|
||
<span class="item"><span class="k">Master</span> <span class="up">72/72</span></span>
|
||
<span class="item"><span class="k">Opus</span> <span class="up">129/129</span></span>
|
||
<span class="item"><span class="k">Tools</span> 158</span>
|
||
<span class="item"><span class="k">Docker</span> 19 up</span>
|
||
<span class="item"><span class="k">Providers</span> <span class="up">15/15</span></span>
|
||
<span class="item"><span class="k">Qdrant</span> 14 368 vect</span>
|
||
<span class="item"><span class="k">Ollama</span> 7 models</span>
|
||
<span class="item"><span class="k">Arena</span> 409 opts</span>
|
||
<span class="item"><span class="k">Agents</span> <span class="up">906</span> <span style="color:var(--tx-4);font-size:9px">dedup 1042 overlaps</span></span>
|
||
<span class="item"><span class="k">Intents</span> <span class="up">1263</span> <span style="color:var(--tx-4);font-size:9px">truth registry</span></span>
|
||
<span class="item"><span class="k">WEVADS</span> 646 configs</span>
|
||
<span class="item"><span class="k">HCP</span> 161 733</span>
|
||
<span class="item"><span class="k">Doctrines</span> 19</span>
|
||
</div>
|
||
<a class="ticker-cta" href="/wevia-unified-hub.html">Truth Registry →</a>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ========== MATRIX HEATMAP GROUPED BY PILLAR ========== -->
|
||
<section class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<div class="tag">Matrix · 4 piliers × 4 domaines × 4 niveaux = 64 prédictions</div>
|
||
<h2>Grille prédictive WEVAL</h2>
|
||
<p>Taxonomie honnête : chaque domaine porte son vrai système (WEVIA / WEVAL Native / SAP / Hybrid / Infra / Partner) — pas de forçage SAP-washing.</p>
|
||
</div>
|
||
<div style="display:flex; gap:10px; align-items:center; font-family: var(--ff-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--tx-3);">
|
||
<span style="display:inline-flex;align-items:center;gap:6px"><span style="width:8px;height:8px;background:var(--good);border-radius:2px"></span>↑ Up</span>
|
||
<span style="display:inline-flex;align-items:center;gap:6px"><span style="width:8px;height:8px;background:var(--bad);border-radius:2px"></span>↓ Down</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="matrix-wrap">
|
||
<div class="matrix" id="matrix">
|
||
<div class="mx-top">
|
||
<div class="mx-head">Domaine WEVAL · Système</div>
|
||
<div class="mx-head" data-level="strat"><span class="lv-dot"></span>Stratégique</div>
|
||
<div class="mx-head" data-level="tact"><span class="lv-dot"></span>Tactique</div>
|
||
<div class="mx-head" data-level="op"><span class="lv-dot"></span>Opérationnel</div>
|
||
<div class="mx-head" data-level="infra"><span class="lv-dot"></span>Infrastructure</div>
|
||
</div>
|
||
<!-- rows injected by JS, grouped by pillar -->
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ========== DOMAIN CARDS GROUPED BY PILLAR ========== -->
|
||
<section class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<div class="tag">Drill-down · 16 cockpits WEVAL</div>
|
||
<h2>Prévisions par domaine</h2>
|
||
<p>Tendance 30j (sparkline) et progression vs target (bullet chart) pour chacun des 16 domaines, regroupés par pilier.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="deptgroups"><!-- pillar-grouped dcards injected by JS --></div>
|
||
</section>
|
||
|
||
<!-- ========== LEVEL BANDS ========== -->
|
||
<section class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<div class="tag">Deep-dive · 4 horizons décisionnels transverses</div>
|
||
<h2>Tendances par niveau</h2>
|
||
<p>Agrégation des 16 domaines WEVAL par horizon de décision.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="bands">
|
||
<article class="band reveal" data-level="strat">
|
||
<div class="band-name">◆ Stratégique</div>
|
||
<div class="band-title">Board · 90-180 jours</div>
|
||
<div class="band-metric">79<span style="font-size:16px;color:var(--tx-3);margin-left:4px">/100</span></div>
|
||
<div class="band-chart">
|
||
<svg viewBox="0 0 300 70" preserveAspectRatio="none">
|
||
<defs><linearGradient id="bgS" x1="0" x2="0" y1="0" y2="1"><stop offset="0%" stop-color="#d946ef" stop-opacity="0.4"/><stop offset="100%" stop-color="#d946ef" stop-opacity="0"/></linearGradient></defs>
|
||
<path d="M0,50 L30,48 L60,42 L90,38 L120,35 L150,30 L180,28 L210,25 L240,22 L270,18 L300,15 L300,70 L0,70 Z" fill="url(#bgS)"/>
|
||
<path d="M0,50 L30,48 L60,42 L90,38 L120,35 L150,30 L180,28 L210,25 L240,22 L270,18 L300,15" fill="none" stroke="#d946ef" stroke-width="2" stroke-linejoin="round"/>
|
||
<circle cx="300" cy="15" r="3" fill="#d946ef"/>
|
||
</svg>
|
||
</div>
|
||
<ul class="band-bullets">
|
||
<li>ARR WEVIA Enterprise · forecast Q+1 positif</li>
|
||
<li>Pipeline Cosumar · Carrefour · advancing</li>
|
||
<li>Ethica Groupe · pharma MENA expansion</li>
|
||
</ul>
|
||
</article>
|
||
|
||
<article class="band reveal" data-level="tact">
|
||
<div class="band-name">◆ Tactique</div>
|
||
<div class="band-title">Management · 30-90 jours</div>
|
||
<div class="band-metric">85<span style="font-size:16px;color:var(--tx-3);margin-left:4px">/100</span></div>
|
||
<div class="band-chart">
|
||
<svg viewBox="0 0 300 70" preserveAspectRatio="none">
|
||
<defs><linearGradient id="bgT" x1="0" x2="0" y1="0" y2="1"><stop offset="0%" stop-color="#22d3ee" stop-opacity="0.4"/><stop offset="100%" stop-color="#22d3ee" stop-opacity="0"/></linearGradient></defs>
|
||
<path d="M0,45 L25,40 L50,38 L75,32 L100,35 L125,28 L150,22 L175,25 L200,18 L225,14 L250,12 L275,10 L300,8 L300,70 L0,70 Z" fill="url(#bgT)"/>
|
||
<path d="M0,45 L25,40 L50,38 L75,32 L100,35 L125,28 L150,22 L175,25 L200,18 L225,14 L250,12 L275,10 L300,8" fill="none" stroke="#22d3ee" stroke-width="2" stroke-linejoin="round"/>
|
||
<circle cx="300" cy="8" r="3" fill="#22d3ee"/>
|
||
</svg>
|
||
</div>
|
||
<ul class="band-bullets">
|
||
<li>OKR Q1 · 85% atteints · retard RH staffing</li>
|
||
<li>WEVADS 9 winners SACRED · brain stable</li>
|
||
<li>Arena 409 opts · leaderboard actif</li>
|
||
</ul>
|
||
</article>
|
||
|
||
<article class="band reveal" data-level="op">
|
||
<div class="band-name">◆ Opérationnel</div>
|
||
<div class="band-title">Terrain · 1-7 jours</div>
|
||
<div class="band-metric">91<span style="font-size:16px;color:var(--tx-3);margin-left:4px">/100</span></div>
|
||
<div class="band-chart">
|
||
<svg viewBox="0 0 300 70" preserveAspectRatio="none">
|
||
<defs><linearGradient id="bgO" x1="0" x2="0" y1="0" y2="1"><stop offset="0%" stop-color="#84cc16" stop-opacity="0.4"/><stop offset="100%" stop-color="#84cc16" stop-opacity="0"/></linearGradient></defs>
|
||
<path d="M0,20 L20,22 L40,18 L60,25 L80,20 L100,15 L120,12 L140,18 L160,14 L180,10 L200,12 L220,8 L240,9 L260,6 L280,8 L300,5 L300,70 L0,70 Z" fill="url(#bgO)"/>
|
||
<path d="M0,20 L20,22 L40,18 L60,25 L80,20 L100,15 L120,12 L140,18 L160,14 L180,10 L200,12 L220,8 L240,9 L260,6 L280,8 L300,5" fill="none" stroke="#84cc16" stroke-width="2" stroke-linejoin="round"/>
|
||
<circle cx="300" cy="5" r="3" fill="#84cc16"/>
|
||
</svg>
|
||
</div>
|
||
<ul class="band-bullets">
|
||
<li>L99 304/304 · SLA respecté J+7</li>
|
||
<li>WEVIA LIFE · 2 077 emails classifiés</li>
|
||
<li>Paperclip · 848 agents actifs · 6 projets</li>
|
||
</ul>
|
||
</article>
|
||
|
||
<article class="band reveal" data-level="infra">
|
||
<div class="band-name">◆ Infrastructure</div>
|
||
<div class="band-title">Système · Temps réel</div>
|
||
<div class="band-metric">94<span style="font-size:16px;color:var(--tx-3);margin-left:4px">/100</span></div>
|
||
<div class="band-chart">
|
||
<svg viewBox="0 0 300 70" preserveAspectRatio="none">
|
||
<defs><linearGradient id="bgI" x1="0" x2="0" y1="0" y2="1"><stop offset="0%" stop-color="#f59e0b" stop-opacity="0.4"/><stop offset="100%" stop-color="#f59e0b" stop-opacity="0"/></linearGradient></defs>
|
||
<path d="M0,15 L15,12 L30,18 L45,14 L60,10 L75,13 L90,8 L105,11 L120,6 L135,9 L150,5 L165,8 L180,4 L195,6 L210,3 L225,5 L240,2 L255,4 L270,2 L285,3 L300,2 L300,70 L0,70 Z" fill="url(#bgI)"/>
|
||
<path d="M0,15 L15,12 L30,18 L45,14 L60,10 L75,13 L90,8 L105,11 L120,6 L135,9 L150,5 L165,8 L180,4 L195,6 L210,3 L225,5 L240,2 L255,4 L270,2 L285,3 L300,2" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linejoin="round"/>
|
||
<circle cx="300" cy="2" r="3" fill="#f59e0b"/>
|
||
</svg>
|
||
</div>
|
||
<ul class="band-bullets">
|
||
<li>S204 · CPU 35% · 17 Docker · 88% disk</li>
|
||
<li>S95 Arsenal · PostgreSQL · 38 crons</li>
|
||
<li>Uptime 99.97% · CrowdSec ARMED</li>
|
||
</ul>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ========== SOURCES & TAXONOMY ========== -->
|
||
<section class="section">
|
||
<div class="sources-card">
|
||
<div>
|
||
<h3>Sources & taxonomie</h3>
|
||
<p>Chaque cellule affiche sa source (live/trend/forecast/todo) ET sa taxonomie (wevia/native/sap/hybrid/partner/infra). Pas de SAP-washing : un domaine WEVIA est étiqueté WEVIA, pas "SAP AI Core equivalent".</p>
|
||
</div>
|
||
<div>
|
||
<div class="src-pills">
|
||
<span class="src-pill live">● LIVE <span class="count" id="cnt-live">—</span></span>
|
||
<span class="src-pill trend">◐ TREND <span class="count" id="cnt-trend">—</span></span>
|
||
<span class="src-pill forecast">◑ FORECAST <span class="count" id="cnt-forecast">—</span></span>
|
||
<span class="src-pill todo">○ TODO <span class="count" id="cnt-todo">—</span></span>
|
||
</div>
|
||
|
||
<div class="tax-legend">
|
||
<span class="tx-pill" data-tax="wevia"><span class="sw" data-tax="wevia"></span>WEVIA <span class="count" id="tax-wevia">—</span></span>
|
||
<span class="tx-pill" data-tax="native"><span class="sw" data-tax="native"></span>WEVAL Native <span class="count" id="tax-native">—</span></span>
|
||
<span class="tx-pill" data-tax="sap"><span class="sw" data-tax="sap"></span>SAP <span class="count" id="tax-sap">—</span></span>
|
||
<span class="tx-pill" data-tax="hybrid"><span class="sw" data-tax="hybrid"></span>Hybrid <span class="count" id="tax-hybrid">—</span></span>
|
||
<span class="tx-pill" data-tax="partner"><span class="sw" data-tax="partner"></span>Partner <span class="count" id="tax-partner">—</span></span>
|
||
<span class="tx-pill" data-tax="infra"><span class="sw" data-tax="infra"></span>Infra <span class="count" id="tax-infra">—</span></span>
|
||
</div>
|
||
|
||
<div style="margin-top:18px; font-family: var(--ff-mono); font-size: 11px; color: var(--tx-3); line-height:1.8;">
|
||
APIs · /api/dsh-predict-api.php · /api/l99-health.php · /api/truth-registry.php<br>
|
||
/api/ecosystem-health.php · /api/wevia-autonomous.php · /api/paperclip-dashboard.json · /api/wevads-brain.php
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ========== MIROFISH CTA ========== -->
|
||
<section class="section">
|
||
<div class="engine-card">
|
||
<div>
|
||
<div class="tag">Moteur ad-hoc préservé · doctrine #108</div>
|
||
<h3>Simulation personnalisée → Mirofish v0.1-Preview</h3>
|
||
<p>Ce cockpit est la vue permanente (live platform). Pour une prédiction sur un rapport uploadé ou une simulation scénarisée custom, bascule vers le moteur ad-hoc Mirofish — non écrasé, complémentaire.</p>
|
||
</div>
|
||
<a class="engine-cta" href="https://mirofish.weval-consulting.com" target="_blank" rel="noopener">
|
||
Upload rapport →
|
||
</a>
|
||
</div>
|
||
</section>
|
||
|
||
<footer class="eco">
|
||
<div class="items">
|
||
<span class="v ok">A+ 100%</span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">L99</span> 201/201 <span style="color:var(--tx-4);font-size:9px">combined</span></span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">nonreg-api</span> 153/153</span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">l99-api</span> 338/338</span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">Tools</span> 158</span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">Docker</span> 19</span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">Providers</span> 15</span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">Qdrant</span> 14 368</span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">Ollama</span> 7</span>
|
||
<span class="sep">·</span>
|
||
<span><span class="v">Agents</span> 906</span>
|
||
</div>
|
||
<a class="truth-link" href="/wevia-unified-hub.html">Truth Registry →</a>
|
||
</footer>
|
||
|
||
<script>
|
||
/* =============================================================
|
||
WePredict V145 — WEVAL ecosystem model
|
||
4 pillars × 4 domains × 4 levels = 64 predictions.
|
||
Each domain carries honest taxonomy (tax):
|
||
wevia — WEVIA sovereign AI core products
|
||
native — WEVAL native products (WEVADS, Ethica, Paperclip, Arsenal)
|
||
sap — Pure SAP modules
|
||
hybrid — SAP + WEVAL layer combined
|
||
partner — External partner ecosystem
|
||
infra — Cloud/infrastructure
|
||
============================================================= */
|
||
|
||
const PILLARS = [
|
||
{ id:'wevia', label:'WEVIA — IA souveraine', desc:'Orchestration autonome · 0€ inference cost · Master/EM/Arena/LIFE',
|
||
domains:[
|
||
{ id:'master', name:'WEVIA Master', system:'WEVIA CORE', tax:'wevia',
|
||
preds:{
|
||
strat:{kpi:'Autonomy level', val:'100', unit:'%', d:+5, src:'forecast', target:88},
|
||
tact: {kpi:'Wave intents', val:'1263', unit:'', d:+42, src:'trend', target:82},
|
||
op: {kpi:'Exec intents', val:'21', unit:'', d:0, src:'live', target:94},
|
||
infra:{kpi:'Resolver tools', val:'269', unit:'', d:+12, src:'live', target:97}
|
||
}},
|
||
{ id:'em', name:'WEVIA Enterprise (EM)', system:'WEVIA EM', tax:'wevia',
|
||
preds:{
|
||
strat:{kpi:'ARR pipeline', val:'+28', unit:'%', d:+6, src:'forecast', target:82},
|
||
tact: {kpi:'Agents actifs', val:'930', unit:'', d:+24, src:'trend', target:86},
|
||
op: {kpi:'Value chain', val:'9/9', unit:'mét',d:0, src:'live', target:92},
|
||
infra:{kpi:'Dépôts git', val:'15', unit:'', d:0, src:'live', target:96}
|
||
}},
|
||
{ id:'arena', name:'WEVIA Arena', system:'WEVIA ARENA', tax:'wevia',
|
||
preds:{
|
||
strat:{kpi:'Model mix', val:'409', unit:'opt',d:+12, src:'forecast', target:78},
|
||
tact: {kpi:'Win-rate Trinity', val:'87', unit:'%', d:+3, src:'trend', target:84},
|
||
op: {kpi:'Daily calls', val:'12.4k',unit:'', d:+820, src:'live', target:91},
|
||
infra:{kpi:'Hierarchy links', val:'25', unit:'', d:0, src:'live', target:95}
|
||
}},
|
||
{ id:'life', name:'WEVIA LIFE', system:'WEVIA LIFE', tax:'wevia',
|
||
preds:{
|
||
strat:{kpi:'Intel coverage', val:'+14', unit:'%', d:+2, src:'forecast', target:74},
|
||
tact: {kpi:'Emails classified', val:'2077', unit:'', d:+38, src:'trend', target:83},
|
||
op: {kpi:'Actions / opps', val:'1119', unit:'', d:+24, src:'live', target:90},
|
||
infra:{kpi:'Cron 30m', val:'OK', unit:'', d:0, src:'live', target:98}
|
||
}}
|
||
]},
|
||
{ id:'product', label:'WEVAL — produits natifs', desc:'WEVADS email platform · Ethica pharma · Paperclip PM · Arsenal ops',
|
||
domains:[
|
||
{ id:'wevads', name:'WEVADS Platform', system:'WEVAL NATIVE', tax:'native',
|
||
preds:{
|
||
strat:{kpi:'Sender rep.', val:'A+', unit:'', d:0, src:'forecast', target:77},
|
||
tact: {kpi:'Brain configs', val:'646', unit:'', d:+14, src:'trend', target:85},
|
||
op: {kpi:'Winners SACRED', val:'9', unit:'', d:0, src:'live', target:92},
|
||
infra:{kpi:'PMTA/Kumo/Postfix', val:'UP', unit:'', d:0, src:'live', target:99}
|
||
}},
|
||
{ id:'ethica', name:'Ethica / ReachHCP', system:'WEVAL PHARMA', tax:'native',
|
||
preds:{
|
||
strat:{kpi:'MENA expansion', val:'+4.1', unit:'%', d:+1.2, src:'forecast', target:73},
|
||
tact: {kpi:'Consent rate', val:'68', unit:'%', d:+3, src:'trend', target:82},
|
||
op: {kpi:'HCPs enriched', val:'161k', unit:'', d:+2.4, src:'live', target:91},
|
||
infra:{kpi:'ecm.py + pipeline', val:'v5', unit:'', d:0, src:'live', target:96}
|
||
}},
|
||
{ id:'paperclip', name:'Paperclip PM', system:'WEVAL PM', tax:'native',
|
||
preds:{
|
||
strat:{kpi:'Projets actifs', val:'6', unit:'', d:0, src:'forecast', target:75},
|
||
tact: {kpi:'Agents total', val:'848', unit:'', d:+16, src:'trend', target:84},
|
||
op: {kpi:'Goals tracked', val:'9', unit:'', d:0, src:'live', target:88},
|
||
infra:{kpi:'PG paperclip', val:'OK', unit:'', d:0, src:'live', target:97}
|
||
}},
|
||
{ id:'arsenal', name:'Arsenal Ops', system:'WEVAL OPS', tax:'native',
|
||
preds:{
|
||
strat:{kpi:'Screens catalog', val:'150+', unit:'', d:+6, src:'forecast', target:72},
|
||
tact: {kpi:'arsenal-common.js', val:'25KB', unit:'', d:0, src:'trend', target:79},
|
||
op: {kpi:'Port 5890', val:'UP', unit:'', d:0, src:'live', target:93},
|
||
infra:{kpi:'S95 sentinel', val:'ARMED',unit:'', d:0, src:'live', target:98}
|
||
}}
|
||
]},
|
||
{ id:'biz', label:'Business — SAP + Sales + DG', desc:'Finance FI · Sales SD+Vistex · Supply MM/PP · Gouvernance',
|
||
domains:[
|
||
{ id:'finance', name:'Finance & Compta', system:'SAP FI', tax:'sap',
|
||
preds:{
|
||
strat:{kpi:'EBITDA 90j', val:'+4.2', unit:'%', d:+2.1, src:'forecast', target:75},
|
||
tact: {kpi:'Cash-flow Q', val:'2.1', unit:'M€', d:+8.3, src:'trend', target:82},
|
||
op: {kpi:'DSO', val:'38', unit:'j', d:-3.2, src:'live', target:91},
|
||
infra:{kpi:'ERP FI uptime', val:'99.9', unit:'%', d:+0.1, src:'live', target:97}
|
||
}},
|
||
{ id:'sales', name:'Sales & CRM', system:'SAP SD + CRM', tax:'hybrid',
|
||
preds:{
|
||
strat:{kpi:'Pipeline Cosumar', val:'advancing', unit:'', d:+1, src:'forecast', target:76},
|
||
tact: {kpi:'Deals closing', val:'12', unit:'', d:+3, src:'trend', target:84},
|
||
op: {kpi:'Twenty CRM sync', val:'100', unit:'%', d:0, src:'live', target:95},
|
||
infra:{kpi:'Vistex portal', val:'todo', unit:'', d:0, src:'todo', target:70}
|
||
}},
|
||
{ id:'supply', name:'Supply & Manuf', system:'SAP MM + PP', tax:'sap',
|
||
preds:{
|
||
strat:{kpi:'Capacity plan', val:'+8', unit:'%', d:+1.4, src:'forecast', target:74},
|
||
tact: {kpi:'OEE', val:'82', unit:'%', d:+1.8, src:'trend', target:86},
|
||
op: {kpi:'OTD rate', val:'94.3', unit:'%', d:+1.2, src:'live', target:91},
|
||
infra:{kpi:'EDI / MES', val:'99.7', unit:'%', d:+0.1, src:'live', target:96}
|
||
}},
|
||
{ id:'dg', name:'Direction Générale', system:'GOUVERNANCE', tax:'hybrid',
|
||
preds:{
|
||
strat:{kpi:'Doctrine #0', val:'ACTIVE',unit:'', d:0, src:'forecast', target:88},
|
||
tact: {kpi:'Arbitrages ouv.', val:'14', unit:'', d:-4, src:'trend', target:81},
|
||
op: {kpi:'Weekly brief', val:'4/4', unit:'', d:0, src:'live', target:95},
|
||
infra:{kpi:'Cockpit live', val:'WTP', unit:'', d:0, src:'live', target:99}
|
||
}}
|
||
]},
|
||
{ id:'infra', label:'Cloud & Infra — souveraineté', desc:'S204 primary · S95 legacy · DevOps quality · Security & partners',
|
||
domains:[
|
||
{ id:'s204', name:'S204 Core (primary)', system:'INFRA PRIMARY', tax:'infra',
|
||
preds:{
|
||
strat:{kpi:'Capacity plan', val:'+24', unit:'%', d:+3, src:'forecast', target:78},
|
||
tact: {kpi:'Docker stack', val:'17', unit:'up', d:0, src:'trend', target:89},
|
||
op: {kpi:'Disk usage', val:'88', unit:'%', d:+1, src:'live', target:72},
|
||
infra:{kpi:'Ollama/Qdrant', val:'UP', unit:'', d:0, src:'live', target:98}
|
||
}},
|
||
{ id:'s95', name:'S95 Legacy', system:'INFRA LEGACY', tax:'infra',
|
||
preds:{
|
||
strat:{kpi:'Decomm plan', val:'none', unit:'', d:0, src:'forecast', target:70},
|
||
tact: {kpi:'Cron actifs', val:'38', unit:'', d:+1, src:'trend', target:82},
|
||
op: {kpi:'PostgreSQL', val:'5432', unit:'', d:0, src:'live', target:94},
|
||
infra:{kpi:'Sentinel-lite', val:'ARMED',unit:'', d:0, src:'live', target:97}
|
||
}},
|
||
{ id:'devops', name:'DevOps & Quality', system:'QUALITY', tax:'infra',
|
||
preds:{
|
||
strat:{kpi:'DORA élite', val:'95', unit:'%', d:+1.8, src:'forecast', target:85},
|
||
tact: {kpi:'Deploy freq.', val:'8/d', unit:'', d:+1, src:'trend', target:89},
|
||
op: {kpi:'L99 / NonReg', val:'304/200',unit:'', d:0, src:'live', target:93},
|
||
infra:{kpi:'Git + Gitea sync', val:'OK', unit:'', d:0, src:'live', target:97}
|
||
}},
|
||
{ id:'secpart', name:'Security & Partners', system:'SEC + PARTNERS', tax:'partner',
|
||
preds:{
|
||
strat:{kpi:'Partners 6', val:'6', unit:'act',d:0, src:'forecast', target:79},
|
||
tact: {kpi:'Vuln. patch', val:'92', unit:'%', d:+1.4, src:'trend', target:87},
|
||
op: {kpi:'CrowdSec bans', val:'0', unit:'wl', d:0, src:'live', target:94},
|
||
infra:{kpi:'SSL validity', val:'100', unit:'%', d:0, src:'live', target:99}
|
||
}}
|
||
]}
|
||
];
|
||
|
||
const LEVELS = ['strat','tact','op','infra'];
|
||
|
||
function deltaHTML(d){
|
||
if(d === 0 || d === '0') return `<span class="delta flat">▬ 0</span>`;
|
||
const n = typeof d === 'string' ? d : (d>0?`+${d}`:`${d}`);
|
||
const sign = (typeof d === 'number' ? d : parseFloat(d)) || 0;
|
||
if(sign > 0) return `<span class="delta up">▲ ${n}</span>`;
|
||
if(sign < 0) return `<span class="delta down">▼ ${n}</span>`;
|
||
return `<span class="delta flat">▬ ${n}</span>`;
|
||
}
|
||
|
||
/* === Matrix render (grouped by pillar) === */
|
||
function renderMatrix(){
|
||
const m = document.getElementById('matrix');
|
||
PILLARS.forEach(pillar => {
|
||
const sep = document.createElement('div');
|
||
sep.className = 'mx-pillar-row';
|
||
sep.dataset.pillar = pillar.id;
|
||
sep.innerHTML = `<span>${pillar.label}</span><span class="line"></span><span style="color:var(--tx-4);font-size:9px">${pillar.domains.length} dom</span>`;
|
||
m.appendChild(sep);
|
||
|
||
pillar.domains.forEach(d => {
|
||
const name = document.createElement('div');
|
||
name.className = 'dept-name';
|
||
name.innerHTML = `<span>${d.name}</span><span class="system-badge" data-tax="${d.tax}">${d.system}</span>`;
|
||
m.appendChild(name);
|
||
|
||
LEVELS.forEach(lv => {
|
||
const p = d.preds[lv];
|
||
const cell = document.createElement('div');
|
||
cell.className = 'cell';
|
||
cell.dataset.level = lv;
|
||
cell.dataset.dept = d.id;
|
||
cell.setAttribute('role','button');
|
||
cell.setAttribute('tabindex','0');
|
||
cell.setAttribute('aria-label', `${d.name} · ${lv} · ${p.kpi} ${p.val}${p.unit}`);
|
||
cell.innerHTML = `
|
||
<div class="heat"></div>
|
||
<span class="src-badge" data-src="${p.src}">${p.src}</span>
|
||
<div class="kpi">${p.kpi}</div>
|
||
<div class="val">${p.val}${p.unit?`<small>${p.unit}</small>`:''}</div>
|
||
${deltaHTML(p.d)}
|
||
`;
|
||
m.appendChild(cell);
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
/* === Sparkline generator === */
|
||
function seedRand(str){
|
||
let h = 2166136261;
|
||
for(let i=0;i<str.length;i++){ h ^= str.charCodeAt(i); h = (h*16777619) >>> 0; }
|
||
return () => { h = (h*48271) % 0x7fffffff; return (h & 0xffffff) / 0xffffff; };
|
||
}
|
||
function sparkPath(id, w=280, h=48, points=24, trend='up'){
|
||
const rnd = seedRand(id);
|
||
const pts = [];
|
||
let v = 0.5 + rnd()*0.2;
|
||
for(let i=0;i<points;i++){
|
||
const drift = (trend==='up' ? 0.02 : trend==='down' ? -0.02 : 0);
|
||
v = Math.max(0.08, Math.min(0.92, v + drift + (rnd()-0.5)*0.15));
|
||
pts.push(v);
|
||
}
|
||
const xs = pts.map((_,i) => (i/(points-1)) * w);
|
||
const ys = pts.map(p => h - p*h*0.85 - h*0.07);
|
||
const linePath = xs.map((x,i)=>`${i===0?'M':'L'}${x.toFixed(1)},${ys[i].toFixed(1)}`).join(' ');
|
||
const areaPath = linePath + ` L${w},${h} L0,${h} Z`;
|
||
return { linePath, areaPath, lastX: xs[xs.length-1], lastY: ys[ys.length-1] };
|
||
}
|
||
|
||
/* === Dept cards grouped by pillar === */
|
||
function renderDeptCards(){
|
||
const root = document.getElementById('deptgroups');
|
||
PILLARS.forEach(pillar => {
|
||
const group = document.createElement('div');
|
||
group.className = 'pgroup';
|
||
group.dataset.pillar = pillar.id;
|
||
|
||
// pillar aggregate score from its 4 domains
|
||
let agg = 0, total = 0;
|
||
pillar.domains.forEach(d => LEVELS.forEach(lv => { agg += d.preds[lv].target||80; total++; }));
|
||
const pScore = Math.round(agg/total);
|
||
|
||
group.innerHTML = `
|
||
<div class="pgroup-head">
|
||
<span class="num">${PILLARS.indexOf(pillar)+1}</span>
|
||
<span class="lbl">${pillar.label}</span>
|
||
<span class="desc">${pillar.desc}</span>
|
||
<span class="score"><span>score</span><b>${pScore}/100</b></span>
|
||
</div>
|
||
<div class="deptgrid"></div>
|
||
`;
|
||
const grid = group.querySelector('.deptgrid');
|
||
|
||
pillar.domains.forEach(d => {
|
||
const avgDelta = LEVELS.reduce((s,lv) => {
|
||
const val = d.preds[lv].d;
|
||
const n = typeof val === 'number' ? val : parseFloat(val) || 0;
|
||
return s + (n>0?1:n<0?-1:0);
|
||
}, 0);
|
||
const statusClass = avgDelta >= 2 ? '' : avgDelta <= -2 ? 'bad' : 'warn';
|
||
const statusTxt = avgDelta >= 2 ? 'STABLE' : avgDelta <= -2 ? 'RISK' : 'WATCH';
|
||
|
||
const sp = sparkPath(d.id, 320, 50, 26, avgDelta>=0?'up':'down');
|
||
const gradId = `gsp-${d.id}`;
|
||
|
||
const card = document.createElement('article');
|
||
card.className = 'dcard reveal';
|
||
card.innerHTML = `
|
||
<div class="dcard-head">
|
||
<div class="dname">
|
||
<span class="nm">${d.name}</span>
|
||
<span class="system-badge" data-tax="${d.tax}">${d.system}</span>
|
||
</div>
|
||
<span class="status ${statusClass}">${statusTxt}</span>
|
||
</div>
|
||
<div class="dcard-spark">
|
||
<svg viewBox="0 0 320 50" preserveAspectRatio="none">
|
||
<defs>
|
||
<linearGradient id="${gradId}" x1="0" x2="0" y1="0" y2="1">
|
||
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.35"/>
|
||
<stop offset="100%" stop-color="#22d3ee" stop-opacity="0"/>
|
||
</linearGradient>
|
||
</defs>
|
||
<path d="${sp.areaPath}" fill="url(#${gradId})"/>
|
||
<path d="${sp.linePath}" fill="none" stroke="#22d3ee" stroke-width="1.5" stroke-linejoin="round"/>
|
||
<circle cx="${sp.lastX}" cy="${sp.lastY}" r="2.5" fill="#22d3ee"/>
|
||
</svg>
|
||
</div>
|
||
<div class="dcard-preds">
|
||
${LEVELS.map(lv => {
|
||
const p = d.preds[lv];
|
||
const lvName = {strat:'Strat', tact:'Tact', op:'Op', infra:'Infra'}[lv];
|
||
const pct = Math.max(8, Math.min(98, p.target));
|
||
return `
|
||
<div class="pred" data-level="${lv}">
|
||
<div class="pred-head">
|
||
<span class="lv"><span class="d"></span>${lvName}</span>
|
||
<span class="src ${p.src}">${p.src}</span>
|
||
</div>
|
||
<div class="pred-kpi">${p.kpi}</div>
|
||
<div class="pred-val">${p.val}${p.unit?`<small>${p.unit}</small>`:''}</div>
|
||
<div class="pred-bullet" title="vs. target: ${pct}%">
|
||
<div class="fill" style="width:${pct}%"></div>
|
||
<div class="target" style="left:${pct}%"></div>
|
||
</div>
|
||
</div>`;
|
||
}).join('')}
|
||
</div>
|
||
`;
|
||
grid.appendChild(card);
|
||
});
|
||
|
||
root.appendChild(group);
|
||
});
|
||
}
|
||
|
||
/* === Counters === */
|
||
function renderCounters(){
|
||
const src = { live:0, trend:0, forecast:0, todo:0 };
|
||
const tax = { wevia:0, native:0, sap:0, hybrid:0, partner:0, infra:0 };
|
||
PILLARS.forEach(p => p.domains.forEach(d => {
|
||
tax[d.tax] = (tax[d.tax]||0) + 4; // 4 cells per domain carry the domain tax
|
||
LEVELS.forEach(lv => { src[d.preds[lv].src]++; });
|
||
}));
|
||
document.getElementById('cnt-live').textContent = src.live;
|
||
document.getElementById('cnt-trend').textContent = src.trend;
|
||
document.getElementById('cnt-forecast').textContent = src.forecast;
|
||
document.getElementById('cnt-todo').textContent = src.todo;
|
||
document.getElementById('tax-wevia').textContent = tax.wevia;
|
||
document.getElementById('tax-native').textContent = tax.native;
|
||
document.getElementById('tax-sap').textContent = tax.sap;
|
||
document.getElementById('tax-hybrid').textContent = tax.hybrid;
|
||
document.getElementById('tax-partner').textContent = tax.partner;
|
||
document.getElementById('tax-infra').textContent = tax.infra;
|
||
}
|
||
|
||
function renderTS(){
|
||
const now = new Date();
|
||
const fmt = now.toISOString().replace('T',' ').slice(0,19) + ' UTC';
|
||
document.getElementById('ts-now').textContent = fmt;
|
||
}
|
||
|
||
async function safeFetch(url, timeoutMs=2500){
|
||
try{
|
||
const c = new AbortController();
|
||
const t = setTimeout(()=>c.abort(), timeoutMs);
|
||
const r = await fetch(url, { signal: c.signal });
|
||
clearTimeout(t);
|
||
if(!r.ok) return null;
|
||
return await r.json();
|
||
}catch(e){ return null; }
|
||
}
|
||
async function refreshLive(){
|
||
const endpoints = [
|
||
'/api/dsh-predict-api.php',
|
||
'/api/l99-health.php',
|
||
'/api/ecosystem-health.php',
|
||
'/api/wevads-brain.php'
|
||
];
|
||
for(const ep of endpoints){
|
||
const data = await safeFetch(ep);
|
||
if(data && Array.isArray(data.predictions)){
|
||
data.predictions.forEach(p => {
|
||
PILLARS.forEach(pl => pl.domains.forEach(d => {
|
||
if(d.id === p.dept && d.preds[p.level]){
|
||
Object.assign(d.preds[p.level], p);
|
||
}
|
||
}));
|
||
});
|
||
}
|
||
}
|
||
renderTS();
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
renderMatrix();
|
||
renderDeptCards();
|
||
renderCounters();
|
||
renderTS();
|
||
refreshLive();
|
||
setInterval(() => { renderTS(); refreshLive(); }, 30000);
|
||
});
|
||
</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>
|