<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>Lojão dos Bonés · BI de Estoque</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600;700&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--bg:#0d1117;
--surf:#161b22;
--surf2:#1c2330;
--brd:#21262d;
--brd2:#30363d;
--red:#c0392b;
--red-m:#e05c52;
--red-d:rgba(192,57,43,.1);
--grn:#27ae60;
--grn-m:#3dbf72;
--grn-d:rgba(39,174,96,.1);
--amb:#c49a25;
--amb-m:#d4aa35;
--amb-d:rgba(196,154,37,.1);
--blu:#2e6da4;
--blu-m:#4484b8;
--blu-d:rgba(46,109,164,.1);
--txt:#e6edf3;
--txt2:#b0bac4;
--mut:#7d8fa1;
--mut2:#4a5968;
--fh:'DM Sans',sans-serif;
--fm:'DM Mono',monospace;
--sb:224px;--tb:50px;--bn:58px;
}
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--txt);font-family:var(--fh);font-size:13px;min-height:100vh;overflow-x:hidden;-webkit-font-smoothing:antialiased}
::-webkit-scrollbar{width:4px;height:4px}
::-webkit-scrollbar-track{background:var(--bg)}
::-webkit-scrollbar-thumb{background:var(--brd2);border-radius:2px}
/* SIDEBAR */
.sidebar{position:fixed;left:0;top:0;bottom:0;width:var(–sb);background:var(–surf);border-right:1px solid var(–brd);display:flex;flex-direction:column;z-index:200;transition:transform .28s ease}
.logo{padding:22px 20px 18px;border-bottom:1px solid var(–brd)}
.logo-tag{font-size:9px;letter-spacing:1.5px;color:var(–mut);text-transform:uppercase;margin-bottom:6px;font-weight:400}
.logo-name{font-family:var(–fh);font-size:16px;font-weight:700;color:var(–txt);line-height:1.2;letter-spacing:-.2px}
.logo-sub{font-size:9px;color:var(–mut);font-weight:400;letter-spacing:.5px;margin-top:4px}
.nav{padding:14px 0;flex:1;overflow-y:auto}
.nav-sec{font-size:9px;letter-spacing:1px;color:var(–mut2);padding:10px 20px 5px;text-transform:uppercase;font-weight:500}
.nav-item{display:flex;align-items:center;gap:10px;padding:8px 20px;cursor:pointer;font-size:12px;color:var(–mut);border-left:2px solid transparent;transition:all .15s;user-select:none;font-weight:400}
.nav-item:hover{color:var(–txt2);background:var(–surf2)}
.nav-item.active{color:var(–txt);background:var(–surf2);border-left-color:var(–red-m);font-weight:500}
.nav-item .ic{font-size:12px;width:16px;text-align:center;flex-shrink:0;opacity:.7}
.sidebar-foot{padding:14px 20px;border-top:1px solid var(–brd);font-size:10px;color:var(–mut2);line-height:1.8}
.dot{display:inline-block;width:5px;height:5px;background:var(–grn-m);border-radius:50%;margin-right:6px;animation:pulse 2.5s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}
/* OVERLAY */
.overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:190;opacity:0;transition:opacity .25s}
.overlay.show{display:block;opacity:1}
/* MAIN */
.main{margin-left:var(–sb);min-height:100vh;display:flex;flex-direction:column}
/* TOPBAR */
.topbar{height:var(–tb);background:var(–surf);border-bottom:1px solid var(–brd);display:flex;align-items:center;justify-content:space-between;padding:0 22px;position:sticky;top:0;z-index:100;flex-shrink:0}
.topbar-l{display:flex;align-items:center;gap:12px}
.hamburger{display:none;background:none;border:none;cursor:pointer;color:var(–mut);font-size:18px;padding:4px;transition:color .15s;line-height:1}
.hamburger:hover{color:var(–txt)}
.page-title{font-size:13px;font-weight:600;color:var(–txt);letter-spacing:-.1px}
.page-badge{background:var(–surf2);border:1px solid var(–brd2);color:var(–mut);font-size:9px;font-weight:500;padding:2px 8px;letter-spacing:.5px}
.date-chip{font-size:10px;color:var(–mut);background:var(–surf2);padding:4px 10px;border:1px solid var(–brd);font-weight:400}
/* CONTENT */
.content{flex:1;padding:22px;overflow-x:hidden}
/* PAGES */
.page{display:none}
.page.active{display:block}
@keyframes fadeUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
.page.active .kpi,.page.active .card,.page.active .cause-card,.page.active .step{animation:fadeUp .28s ease both}
.page.active .kpi:nth-child(1){animation-delay:.04s}
.page.active .kpi:nth-child(2){animation-delay:.08s}
.page.active .kpi:nth-child(3){animation-delay:.12s}
.page.active .kpi:nth-child(4){animation-delay:.16s}
/* SECTION */
.sec-title{font-size:18px;font-weight:700;margin-bottom:4px;letter-spacing:-.3px;color:var(–txt)}
.sec-sub{font-size:11px;color:var(–mut);margin-bottom:18px;line-height:1.5}
/* KPI */
.kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}
.kpi-3{grid-template-columns:repeat(3,1fr)}
.kpi{background:var(–surf);border:1px solid var(–brd);padding:18px 20px;position:relative;overflow:hidden;transition:border-color .2s}
.kpi:hover{border-color:var(–brd2)}
.kpi::after{content:’’;position:absolute;top:0;left:0;right:0;height:2px;opacity:.75}
.kpi.red::after{background:var(–red-m)}.kpi.grn::after{background:var(–grn-m)}
.kpi.amb::after{background:var(–amb-m)}.kpi.blu::after{background:var(–blu-m)}
.kpi-lbl{font-size:10px;color:var(–mut);margin-bottom:9px;font-weight:500;letter-spacing:.1px}
.kpi-val{font-family:var(–fm);font-size:24px;font-weight:500;line-height:1;margin-bottom:6px;letter-spacing:-.5px}
.kpi.red .kpi-val{color:var(–red-m)}.kpi.grn .kpi-val{color:var(–grn-m)}
.kpi.amb .kpi-val{color:var(–amb-m)}.kpi.blu .kpi-val{color:var(–blu-m)}
.kpi-sub{font-size:10px;color:var(–mut);font-weight:400}
.kpi-ico{position:absolute;right:16px;top:16px;font-size:18px;opacity:.08}
/* CARD */
.card{background:var(–surf);border:1px solid var(–brd);overflow:hidden}
.card-hd{padding:12px 18px;border-bottom:1px solid var(–brd);display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:6px}
.card-title{font-size:10px;font-weight:600;color:var(–txt2);letter-spacing:.3px;text-transform:uppercase}
.card-tag{font-size:9px;color:var(–mut);padding:2px 8px;background:var(–surf2);border:1px solid var(–brd)}
.card-body{padding:18px}
/* GRIDS */
.g2{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px}
.g6040{display:grid;grid-template-columns:60fr 40fr;gap:12px;margin-bottom:12px}
.mb{margin-bottom:12px}
/* CHARTS */
.chart-wrap canvas{max-height:220px}
.chart-wrap.tall canvas{max-height:270px}
/* TABLES */
.tbl-ctrl{padding:10px 14px;border-bottom:1px solid var(–brd);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.srch{background:var(–surf2);border:1px solid var(–brd);color:var(–txt);font-family:var(–fh);font-size:12px;padding:7px 10px;outline:none;flex:1;min-width:120px;transition:border-color .2s;border-radius:0}
.srch::placeholder{color:var(–mut2)}.srch:focus{border-color:var(–brd2)}
.fbt{background:var(–surf2);border:1px solid var(–brd);color:var(–mut);font-family:var(–fh);font-size:10px;font-weight:500;padding:6px 10px;cursor:pointer;transition:all .15s;white-space:nowrap;letter-spacing:.2px}
.fbt:hover,.fbt.on{color:var(–txt2);border-color:var(–brd2);background:var(–brd)}
.fbt.red.on{border-color:var(–red-m);color:var(–red-m);background:var(–red-d)}
.fbt.grn.on{border-color:var(–grn-m);color:var(–grn-m);background:var(–grn-d)}
.fbt.amb.on{border-color:var(–amb-m);color:var(–amb-m);background:var(–amb-d)}
.tbl-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;max-height:460px;overflow-y:auto}
.tbl-scroll table{width:100%;border-collapse:collapse;min-width:500px}
table th{padding:9px 12px;text-align:left;font-size:9px;letter-spacing:.8px;color:var(–mut2);text-transform:uppercase;font-weight:600;border-bottom:1px solid var(–brd);background:var(–surf2);cursor:pointer;user-select:none;white-space:nowrap;position:sticky;top:0;z-index:2;font-family:var(–fh)}
table th:hover{color:var(–mut)}
table th.sa::after{content:’ ↑’;color:var(–blu-m)}table th.sd::after{content:’ ↓’;color:var(–blu-m)}
table tbody tr{border-bottom:1px solid var(–brd);transition:background .12s}
table tbody tr:hover{background:var(–surf2)}
table tbody tr:last-child{border-bottom:none}
table tbody td{padding:9px 12px;font-size:12px}
.tbl-foot{padding:8px 14px;border-top:1px solid var(–brd);font-size:9px;color:var(–mut2);display:flex;justify-content:space-between;flex-wrap:wrap;gap:4px}
/* HELPERS */
.mono{font-family:var(–fm)}
.cr{color:var(–red-m)}.cg{color:var(–grn-m)}
.ca{color:var(–amb-m)}.cm{color:var(–mut)}
.badge{display:inline-block;padding:2px 8px;font-size:9px;font-weight:600;letter-spacing:.5px}
.br{background:var(–red-d);color:var(–red-m);border:1px solid rgba(224,92,82,.2)}
.bg{background:var(–grn-d);color:var(–grn-m);border:1px solid rgba(61,191,114,.2)}
.ba{background:var(–amb-d);color:var(–amb-m);border:1px solid rgba(212,170,53,.2)}
.bb{background:var(–blu-d);color:var(–blu-m);border:1px solid rgba(68,132,184,.2)}
.bk{background:var(–surf2);color:var(–mut);border:1px solid var(–brd)}
/* PROGRESS */
.pr{margin-bottom:11px}
.pl{display:flex;justify-content:space-between;font-size:10px;margin-bottom:5px;color:var(–mut);flex-wrap:wrap;gap:2px;font-family:var(–fh)}
.pt{height:2px;background:var(–brd);overflow:hidden}
.pf{height:100%;transition:width 1s ease}
/* MINI LIST */
.ml{display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid var(–brd);font-size:12px}
.ml:last-child{border-bottom:none}
/* CAUSES */
.cause-card{background:var(–surf);border:1px solid var(–brd);padding:20px;margin-bottom:10px;display:grid;grid-template-columns:48px 1fr auto;gap:18px;align-items:start}
.cn{width:48px;height:48px;display:flex;align-items:center;justify-content:center;font-family:var(–fm);font-size:18px;font-weight:500;border:1px solid;flex-shrink:0;border-radius:2px}
.cn.red{color:var(–red-m);border-color:rgba(224,92,82,.3);background:var(–red-d)}
.cn.amb{color:var(–amb-m);border-color:rgba(212,170,53,.3);background:var(–amb-d)}
.cn.blu{color:var(–blu-m);border-color:rgba(68,132,184,.3);background:var(–blu-d)}
.ct{font-size:13px;font-weight:600;margin-bottom:8px;color:var(–txt);letter-spacing:-.1px}
.cb{font-size:11.5px;color:var(–mut);line-height:1.75}
/* STEPS */
.step{display:flex;gap:18px;margin-bottom:22px;align-items:flex-start}
.sn{min-width:36px;height:36px;display:flex;align-items:center;justify-content:center;font-family:var(–fm);font-size:16px;font-weight:500;color:var(–bg);flex-shrink:0;margin-top:2px;border-radius:2px}
.stitle{font-size:13px;font-weight:600;color:var(–grn-m);margin-bottom:6px;letter-spacing:-.1px}
.stxt{font-size:11.5px;color:var(–mut);line-height:1.8}
.stags{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap}
.stag{font-size:9px;color:var(–mut2);background:var(–surf2);padding:3px 9px;border:1px solid var(–brd);font-weight:500}
/* BOTTOM NAV */
.bottom-nav{display:none;position:fixed;bottom:0;left:0;right:0;background:var(–surf);border-top:1px solid var(–brd);z-index:200;height:var(–bn)}
.bni{display:flex;height:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
.bn{flex:1;min-width:56px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;cursor:pointer;color:var(–mut);font-size:7px;letter-spacing:.2px;padding:4px 2px;transition:color .15s;border-top:2px solid transparent;user-select:none;text-align:center;font-weight:500}
.bn.active{color:var(–red-m);border-top-color:var(–red-m)}
.bn .bic{font-size:14px;line-height:1}
/* ─── RESPONSIVE ─── */
@media(max-width:1100px){
:root{–sb:200px}
.kpi-val{font-size:20px}
.g6040{grid-template-columns:1fr}
}
@media(max-width:860px){
:root{–sb:0px}
.sidebar{transform:translateX(-224px);width:224px}
.sidebar.open{transform:translateX(0)}
.main{margin-left:0;padding-bottom:var(–bn)}
.hamburger{display:block}
.bottom-nav{display:block}
.kpi-grid{grid-template-columns:repeat(2,1fr)}
.kpi-3{grid-template-columns:repeat(2,1fr)}
.g2{grid-template-columns:1fr}
.g6040{grid-template-columns:1fr}
.date-chip{display:none}
.cause-card{grid-template-columns:44px 1fr;grid-template-rows:auto auto}
.cause-card>span{grid-column:2;justify-self:start}
.risk-grid{grid-template-columns:1fr!important}
}
@media(max-width:560px){
.content{padding:12px}
.kpi-grid{grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px}
.kpi-3{grid-template-columns:1fr 1fr}
.kpi{padding:13px 14px}
.kpi-val{font-size:18px}
.kpi-lbl{font-size:9px}
.cause-card{padding:14px;gap:10px}
.cn{width:40px;height:40px;font-size:15px}
.ct{font-size:12px}
.sec-title{font-size:16px}
.step{gap:10px}
.sn{min-width:30px;height:30px;font-size:14px}
.page-title{font-size:12px}
.page-badge{display:none}
.card-body{padding:12px}
.chart-wrap canvas{max-height:180px}
.chart-wrap.tall canvas{max-height:210px}
}
@media(max-width:380px){
.kpi-grid,.kpi-3{grid-template-columns:1fr}
.content{padding:10px}
}
</style>
</head>
<body>
<div class="overlay" id="ov" onclick="closeSB()"></div>
<!-- SIDEBAR -->
<div class="sidebar" id="sb">
<div class="logo">
<div class="logo-tag">Sistema de Auditoria</div>
<div class="logo-name">Lojão dos Bonés</div>
<div class="logo-sub">BI de Estoque · Abril 2025</div>
</div>
<nav class="nav">
<div class="nav-sec">Painel</div>
<div class="nav-item active" onclick="go('dashboard',this)"><span class="ic">◈</span>Dashboard</div>
<div class="nav-sec">Análise</div>
<div class="nav-item" onclick="go('faltas',this)"><span class="ic">▼</span>Divergências Negativas</div>
<div class="nav-item" onclick="go('sobras',this)"><span class="ic">▲</span>Divergências Positivas</div>
<div class="nav-item" onclick="go('inventario',this)"><span class="ic">≡</span>Inventário Completo</div>
<div class="nav-sec">Diagnóstico</div>
<div class="nav-item" onclick="go('causas',this)"><span class="ic">◎</span>Causas Prováveis</div>
<div class="nav-item" onclick="go('plano',this)"><span class="ic">→</span>Plano de Ação</div>
</nav>
<div class="sidebar-foot">
<div><span class="dot"></span>Sistema ativo</div>
<div>Conferência concluída</div>
<div>170 SKUs analisados</div>
</div>
</div>
<!-- MAIN -->
<div class="main">
<div class="topbar">
<div class="topbar-l">
<button class="hamburger" onclick="openSB()" aria-label="Menu">☰</button>
<div class="page-title" id="ttl">Dashboard</div>
<div class="page-badge" id="bdg">VISÃO GERAL</div>
</div>
<div class="date-chip">Abril 2025 · Conferência Concluída</div>
</div>
<div class="content">
```
<!-- ═══ DASHBOARD ═══ -->
<div class="page active" id="pg-dashboard">
<div class="kpi-grid">
<div class="kpi red"><div class="kpi-lbl">Prejuízo Patrimonial</div><div class="kpi-val">R$ 40.911</div><div class="kpi-sub">Diferença líquida (Faltas − Sobras)</div><div class="kpi-ico">⚠</div></div>
<div class="kpi amb"><div class="kpi-lbl">Total Faltas (custo)</div><div class="kpi-val">R$ 60.489</div><div class="kpi-sub">Itens com contagem menor</div><div class="kpi-ico">▼</div></div>
<div class="kpi grn"><div class="kpi-lbl">Total Sobras (custo)</div><div class="kpi-val">R$ 19.577</div><div class="kpi-sub">Capital imobilizado</div><div class="kpi-ico">▲</div></div>
<div class="kpi blu"><div class="kpi-lbl">SKUs Auditados</div><div class="kpi-val">170</div><div class="kpi-sub">Em 2 dias de conferência</div><div class="kpi-ico">≡</div></div>
</div>
<div class="g6040">
<div class="card mb">
<div class="card-hd"><div class="card-title">Composição do Resultado</div><div class="card-tag">a preço de custo</div></div>
<div class="card-body"><div class="chart-wrap tall"><canvas id="cComp"></canvas></div></div>
</div>
<div class="card mb">
<div class="card-hd"><div class="card-title">Distribuição por Status</div><div class="card-tag">% SKUs</div></div>
<div class="card-body">
<div class="chart-wrap"><canvas id="cSt"></canvas></div>
<div style="margin-top:14px">
<div class="ml"><span>✓ Sem divergência</span><span class="mono cm">~62 SKUs</span></div>
<div class="ml"><span>▼ Com falta</span><span class="mono cr">45 SKUs</span></div>
<div class="ml"><span>▲ Com sobra</span><span class="mono cg">38 SKUs</span></div>
<div class="ml"><span>∅ Zerado / Inativo</span><span class="mono cm">25 SKUs</span></div>
</div>
</div>
</div>
</div>
<div class="g2">
<div class="card mb">
<div class="card-hd"><div class="card-title">Top 6 — Maiores Faltas</div><div class="card-tag">impacto R$</div></div>
<div class="card-body"><div class="chart-wrap tall"><canvas id="cTF"></canvas></div></div>
</div>
<div class="card mb">
<div class="card-hd"><div class="card-title">Top 5 — Maiores Sobras</div><div class="card-tag">valor imobilizado</div></div>
<div class="card-body"><div class="chart-wrap tall"><canvas id="cTS"></canvas></div></div>
</div>
</div>
<div class="card mb">
<div class="card-hd"><div class="card-title">Exposição ao Risco por Item</div><div class="card-tag">escala de impacto</div></div>
<div class="card-body">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:28px" class="risk-grid">
<div>
<div style="font-size:9px;letter-spacing:1px;color:var(--red-m);margin-bottom:12px;font-weight:600;text-transform:uppercase">▼ Faltas</div>
<div class="pr"><div class="pl"><span>Boné Time Cap (−3.852 un)</span><span class="cr">R$ 46.224</span></div><div class="pt"><div class="pf" style="width:76%;background:var(--red-m)"></div></div></div>
<div class="pr"><div class="pl"><span>Boné Truck Infantil (−253 un)</span><span class="cr">R$ 3.036</span></div><div class="pt"><div class="pf" style="width:18%;background:var(--red-m)"></div></div></div>
<div class="pr"><div class="pl"><span>Boné Tactel Liso (−419 un)</span><span class="cr">R$ 1.676</span></div><div class="pt"><div class="pf" style="width:14%;background:var(--amb-m)"></div></div></div>
<div class="pr"><div class="pl"><span>Boné Classic (−83 un)</span><span class="cr">R$ 1.494</span></div><div class="pt"><div class="pf" style="width:12%;background:var(--amb-m)"></div></div></div>
<div class="pr"><div class="pl"><span>Boné Snapback GLX (−95 un)</span><span class="cr">R$ 1.330</span></div><div class="pt"><div class="pf" style="width:10%;background:var(--amb-m)"></div></div></div>
</div>
<div>
<div style="font-size:9px;letter-spacing:1px;color:var(--grn-m);margin-bottom:12px;font-weight:600;text-transform:uppercase">▲ Sobras</div>
<div class="pr"><div class="pl"><span>Boné Telado Cap (+1.086 un)</span><span class="cg">R$ 11.946</span></div><div class="pt"><div class="pf" style="width:61%;background:var(--grn-m)"></div></div></div>
<div class="pr"><div class="pl"><span>Boné Belém Cap (+280 un)</span><span class="cg">R$ 3.360</span></div><div class="pt"><div class="pf" style="width:17%;background:var(--grn-m)"></div></div></div>
<div class="pr"><div class="pl"><span>Boné Truck GLX (+95 un)</span><span class="cg">R$ 1.568</span></div><div class="pt"><div class="pf" style="width:8%;background:var(--grn-m)"></div></div></div>
<div class="pr"><div class="pl"><span>Boné Telado Liso (+172 un)</span><span class="cg">R$ 1.118</span></div><div class="pt"><div class="pf" style="width:6%;background:var(--grn-m)"></div></div></div>
<div class="pr"><div class="pl"><span>Boné Premium R$17 (+32 un)</span><span class="cg">R$ 544</span></div><div class="pt"><div class="pf" style="width:3%;background:var(--grn-m)"></div></div></div>
</div>
</div>
</div>
</div>
</div>
<!-- ═══ FALTAS ═══ -->
<div class="page" id="pg-faltas">
<div class="sec-title">Divergências Negativas</div>
<div class="sec-sub">Itens com contagem física menor que o saldo registrado no sistema</div>
<div class="kpi-grid kpi-3">
<div class="kpi red"><div class="kpi-lbl">Total (Custo)</div><div class="kpi-val">R$ 60.489</div><div class="kpi-sub">A preço de compra</div></div>
<div class="kpi amb"><div class="kpi-lbl">Maior Perda (1 item)</div><div class="kpi-val">R$ 46.224</div><div class="kpi-sub">Boné Time Cap · −3.852 un</div></div>
<div class="kpi red"><div class="kpi-lbl">SKUs com Falta</div><div class="kpi-val">45</div><div class="kpi-sub">Abaixo do saldo sistêmico</div></div>
</div>
<div class="g2">
<div class="card mb"><div class="card-hd"><div class="card-title">Ranking por Impacto</div></div><div class="card-body"><div class="chart-wrap tall"><canvas id="cFB"></canvas></div></div></div>
<div class="card mb"><div class="card-hd"><div class="card-title">Participação no Total</div></div><div class="card-body"><div class="chart-wrap tall"><canvas id="cFP"></canvas></div></div></div>
</div>
<div class="card mb">
<div class="card-hd"><div class="card-title">Itens com Falta</div></div>
<div class="tbl-scroll">
<table id="tF"><thead><tr>
<th onclick="srt('tF',0)">Produto</th><th onclick="srt('tF',1)">Sistema</th><th onclick="srt('tF',2)">Contagem</th>
<th onclick="srt('tF',3)">Diferença</th><th onclick="srt('tF',4)">P. Custo</th><th onclick="srt('tF',5)">Impacto</th><th onclick="srt('tF',6)">Sev.</th>
</tr></thead><tbody id="bF"></tbody></table>
</div>
<div class="tbl-foot"><span id="cF">—</span><span>↕ Clique no cabeçalho para ordenar</span></div>
</div>
</div>
<!-- ═══ SOBRAS ═══ -->
<div class="page" id="pg-sobras">
<div class="sec-title">Divergências Positivas</div>
<div class="sec-sub">Itens com contagem física maior que o saldo sistêmico · Capital imobilizado não reconhecido</div>
<div class="kpi-grid kpi-3">
<div class="kpi grn"><div class="kpi-lbl">Total (Custo)</div><div class="kpi-val">R$ 19.577</div><div class="kpi-sub">Capital imobilizado invisível</div></div>
<div class="kpi grn"><div class="kpi-lbl">Maior Sobra (1 item)</div><div class="kpi-val">+1.086</div><div class="kpi-sub">Boné Telado Cap · R$ 11.946</div></div>
<div class="kpi blu"><div class="kpi-lbl">SKUs com Sobra</div><div class="kpi-val">38</div><div class="kpi-sub">Acima do saldo sistêmico</div></div>
</div>
<div class="g2">
<div class="card mb"><div class="card-hd"><div class="card-title">Ranking por Valor</div></div><div class="card-body"><div class="chart-wrap tall"><canvas id="cSB"></canvas></div></div></div>
<div class="card mb"><div class="card-hd"><div class="card-title">Participação no Total</div></div><div class="card-body"><div class="chart-wrap tall"><canvas id="cSP"></canvas></div></div></div>
</div>
<div class="card mb">
<div class="card-hd"><div class="card-title">Itens com Sobra</div></div>
<div class="tbl-scroll">
<table id="tS"><thead><tr>
<th onclick="srt('tS',0)">Produto</th><th onclick="srt('tS',1)">Sistema</th><th onclick="srt('tS',2)">Contagem</th>
<th onclick="srt('tS',3)">Diferença</th><th onclick="srt('tS',4)">P. Custo</th><th onclick="srt('tS',5)">Val. Imob.</th>
</tr></thead><tbody id="bS"></tbody></table>
</div>
<div class="tbl-foot"><span id="cS">—</span><span>↕ Ordenar por coluna</span></div>
</div>
</div>
<!-- ═══ INVENTÁRIO ═══ -->
<div class="page" id="pg-inventario">
<div class="sec-title">Inventário Completo</div>
<div class="sec-sub">Todos os SKUs conferidos · Busca e filtro por status</div>
<div class="card mb">
<div class="tbl-ctrl">
<input class="srch" id="srch" placeholder="Buscar produto..." oninput="filterInv()">
<button class="fbt on" id="bT" onclick="setF('todos')">Todos</button>
<button class="fbt red" id="bFa" onclick="setF('falta')">▼ Falta</button>
<button class="fbt grn" id="bSo" onclick="setF('sobra')">▲ Sobra</button>
<button class="fbt amb" id="bOk" onclick="setF('ok')">✓ OK</button>
</div>
<div class="tbl-scroll">
<table id="tI"><thead><tr>
<th onclick="srt('tI',0)">Cód</th><th onclick="srt('tI',1)">Produto</th><th onclick="srt('tI',2)">Sistema</th>
<th onclick="srt('tI',3)">Contagem</th><th onclick="srt('tI',4)">Diferença</th><th onclick="srt('tI',5)">P. Custo</th>
<th onclick="srt('tI',6)">Impacto</th><th onclick="srt('tI',7)">Status</th>
</tr></thead><tbody id="bI"></tbody></table>
</div>
<div class="tbl-foot"><span id="cI">—</span><span>↕ Clique no cabeçalho para ordenar</span></div>
</div>
</div>
<!-- ═══ CAUSAS ═══ -->
<div class="page" id="pg-causas">
<div class="sec-title">Parecer Técnico</div>
<div class="sec-sub">Causas prováveis das divergências identificadas na auditoria</div>
<div class="cause-card">
<div class="cn red">01</div>
<div><div class="ct">Mistura Física de Produtos</div><div class="cb">Principal causa das divergências cruzadas. Produtos com códigos diferentes armazenados juntos induzem o operador a registrar vendas pelo código errado. <strong style="color:var(--txt2)">Evidência:</strong> Boné Time Cap falta 3.852 un enquanto Boné Telado Cap tem sobra de 1.086 — produtos visualmente semelhantes no mesmo setor.</div></div>
<span class="badge br">CRÍTICO</span>
</div>
<div class="cause-card">
<div class="cn red">02</div>
<div><div class="ct">Ausência de Conferência Cega no Recebimento</div><div class="cb">Mercadorias entram sem contagem independente antes de dar entrada no sistema. Erros de quantidade e código se acumulam desde a origem e só aparecem na auditoria — já misturados com erros de venda.</div></div>
<span class="badge br">CRÍTICO</span>
</div>
<div class="cause-card">
<div class="cn amb">03</div>
<div><div class="ct">Possíveis Furtos Internos ou Externos</div><div class="cb">O volume e a especificidade das perdas — Boné Time Cap com déficit de R$ 46.224 — sugerem furto sistemático. Recomenda-se cruzar datas de venda, turnos e câmeras de segurança nos períodos de maior discrepância.</div></div>
<span class="badge ba">ALTO</span>
</div>
<div class="cause-card">
<div class="cn amb">04</div>
<div><div class="ct">Digitação Manual de Códigos no PDV</div><div class="cb">Um dígito trocado registra baixa no produto errado. Mesmo um erro por turno acumula centenas de divergências por mês — exatamente o padrão cruzado encontrado na auditoria.</div></div>
<span class="badge ba">ALTO</span>
</div>
<div class="cause-card">
<div class="cn blu">05</div>
<div><div class="ct">Falta de Endereçamento Logístico</div><div class="cb">Sem localização física definida por SKU, a auditoria levou 2 dias inteiros. Com endereçamento adequado (corredor, prateleira, posição) o mesmo processo levaria poucas horas.</div></div>
<span class="badge bb">MÉDIO</span>
</div>
</div>
<!-- ═══ PLANO ═══ -->
<div class="page" id="pg-plano">
<div class="sec-title">Plano de Ação</div>
<div class="sec-sub">3 medidas corretivas prioritárias para reequilíbrio operacional</div>
<div class="g2">
<div class="card mb">
<div class="card-hd"><div class="card-title">Impacto Esperado</div></div>
<div class="card-body"><div class="chart-wrap tall"><canvas id="cRad"></canvas></div></div>
</div>
<div class="card mb">
<div class="card-hd"><div class="card-title">Resumo Executivo</div></div>
<div class="card-body">
<div class="ml"><span>Prejuízo identificado</span><span class="mono cr">R$ 40.911</span></div>
<div class="ml"><span>Custo estimado de ação</span><span class="mono ca">R$ 3–8k</span></div>
<div class="ml"><span>Payback estimado</span><span class="mono cg">< 60 dias</span></div>
<div class="ml"><span>Redução de divergências</span><span class="mono cg">~85%</span></div>
<div class="ml"><span>Tempo de auditoria (pós)</span><span class="mono cg">2h – 8h</span></div>
<div style="background:var(--red-d);border:1px solid rgba(224,92,82,.18);padding:14px;margin-top:16px">
<div style="font-size:9px;color:var(--red-m);font-weight:600;margin-bottom:6px;letter-spacing:.5px;text-transform:uppercase">⚠ Urgência</div>
<div style="font-size:11.5px;color:var(--mut);line-height:1.75">Cada mês sem ação representa acúmulo de divergências. O prejuízo de R$ 40.911 é o custo do passado — o futuro depende do que for feito agora.</div>
</div>
</div>
</div>
</div>
<div class="card mb">
<div class="card-hd"><div class="card-title">Passos de Implementação</div></div>
<div class="card-body">
<div class="step">
<div class="sn" style="background:var(--grn-m)">1</div>
<div>
<div class="stitle">Bipagem Obrigatória e Automação do PDV</div>
<div class="stxt">Etiquetar 100% dos SKUs com código de barras único e tornar a leitura obrigatória no PDV — se o produto não for bipado, a venda não é processada. Elimina a digitação manual, principal fonte de erro crônico. O investimento se paga em menos de 2 meses considerando apenas a redução de perdas por erro de código.</div>
<div class="stags"><span class="stag">2 semanas</span><span class="stag">R$ 1–3k</span><span class="stag">−70% dos erros</span></div>
</div>
</div>
<div class="step">
<div class="sn" style="background:var(--amb-m)">2</div>
<div>
<div class="stitle" style="color:var(--amb-m)">Endereçamento e Organização por Famílias</div>
<div class="stxt">Criar endereços fixos (corredor, prateleira, posição) para cada SKU e agrupar por família e modelo, com identificação visual clara. Resolve a mistura física que gera divergências cruzadas e reduz futuras conferências de 2 dias para poucas horas.</div>
<div class="stags"><span class="stag">3–5 dias</span><span class="stag">Horas de equipe</span><span class="stag">−90% no tempo de auditoria</span></div>
</div>
</div>
<div class="step">
<div class="sn" style="background:var(--blu-m)">3</div>
<div>
<div class="stitle" style="color:var(--blu-m)">Inventário Rotativo Diário</div>
<div class="stxt">Substituir a grande contagem anual por ciclos rotativos: 10–20 SKUs contados diariamente. Em 8–12 semanas todo o estoque terá sido conferido — com divergências capturadas em tempo real, antes de virarem prejuízo acumulado.</div>
<div class="stags"><span class="stag">Início imediato</span><span class="stag">30 min/dia</span><span class="stag">Detecção em tempo real</span></div>
</div>
</div>
</div>
</div>
</div>
```
</div><!-- /content -->
</div><!-- /main -->
<!-- BOTTOM NAV -->
<div class="bottom-nav">
<div class="bni">
<div class="bn active" id="bn-dashboard" onclick="go('dashboard',null)"><div class="bic">◈</div>Dashboard</div>
<div class="bn" id="bn-faltas" onclick="go('faltas',null)"><div class="bic">▼</div>Faltas</div>
<div class="bn" id="bn-sobras" onclick="go('sobras',null)"><div class="bic">▲</div>Sobras</div>
<div class="bn" id="bn-inventario" onclick="go('inventario',null)"><div class="bic">≡</div>Inventário</div>
<div class="bn" id="bn-causas" onclick="go('causas',null)"><div class="bic">◎</div>Causas</div>
<div class="bn" id="bn-plano" onclick="go('plano',null)"><div class="bic">→</div>Plano</div>
</div>
</div>
<script>
/* ── NAV ── */
const PG = {
dashboard:'Dashboard|VISÃO GERAL',
faltas:'Divergências Negativas|FALTAS',
sobras:'Divergências Positivas|SOBRAS',
inventario:'Inventário Completo|TODOS OS SKUs',
causas:'Causas Prováveis|PARECER TÉCNICO',
plano:'Plano de Ação|PRÓXIMOS PASSOS'
};
function go(id, navEl) {
document.querySelectorAll('.page').forEach(p=>p.classList.remove('active'));
document.getElementById('pg-'+id).classList.add('active');
document.querySelectorAll('.nav-item').forEach(n=>n.classList.remove('active'));
if(navEl) navEl.classList.add('active');
else document.querySelectorAll('.nav-item').forEach(n=>{
if(n.getAttribute('onclick')&&n.getAttribute('onclick').includes("'"+id+"'"))n.classList.add('active')
});
document.querySelectorAll('.bn').forEach(b=>b.classList.remove('active'));
const bn=document.getElementById('bn-'+id);if(bn)bn.classList.add('active');
const [t,b]=PG[id].split('|');
document.getElementById('ttl').textContent=t;
document.getElementById('bdg').textContent=b;
closeSB();window.scrollTo(0,0);
}
function openSB(){document.getElementById('sb').classList.add('open');document.getElementById('ov').classList.add('show')}
function closeSB(){document.getElementById('sb').classList.remove('open');document.getElementById('ov').classList.remove('show')}
/* ── DATA ── */
const inv=[
{cod:1,nome:'BALA CLAVA',sis:8,cnt:3,custo:5},
{cod:2,nome:'BALA CLAVA LONGA',sis:234,cnt:234,custo:8.5},
{cod:3,nome:'BOINA GLX',sis:821,cnt:821,custo:11.5},
{cod:7,nome:'BOLSA (D)',sis:135,cnt:153,custo:15},
{cod:8,nome:'BOLSA ESPORTIVA',sis:55,cnt:51,custo:30},
{cod:9,nome:'BOLSA TELES',sis:9,cnt:27,custo:43},
{cod:10,nome:'BOLSA TRANVERSAL',sis:100,cnt:101,custo:10},
{cod:12,nome:'BONE 6 GMO EMPORT GLX',sis:114,cnt:138,custo:13.9},
{cod:16,nome:'BONE BELEM CAP',sis:1693,cnt:1973,custo:12},
{cod:17,nome:'BONE BLACK BULL',sis:1608,cnt:1641,custo:14.5},
{cod:20,nome:'BONE DEAD HEAD CAP',sis:4191,cnt:4192,custo:12},
{cod:22,nome:'BONE GURGURINO',sis:2801,cnt:2811,custo:7},
{cod:24,nome:'BONE TACTEL LISO',sis:6545,cnt:6126,custo:4},
{cod:26,nome:'BONE LISO CAP',sis:0,cnt:442,custo:11.5},
{cod:27,nome:'BONE PREMIUM R$14',sis:17520,cnt:17507,custo:14},
{cod:28,nome:'BONE PREMIUM R$17',sis:224,cnt:256,custo:17},
{cod:30,nome:'BONE PREMIUM R$20',sis:861,cnt:785,custo:20},
{cod:31,nome:'BONE PRIMEIRA LINHA',sis:2105,cnt:2105,custo:16.5},
{cod:33,nome:'BONE SNAPBACK GLX',sis:222,cnt:127,custo:14},
{cod:34,nome:'BONE TACTEL ESPORTE GLX',sis:620,cnt:574,custo:12},
{cod:35,nome:'BONE TACTEL REFLETIVO',sis:2877,cnt:2838,custo:6.5},
{cod:36,nome:'BONE TELADO LISO',sis:1373,cnt:1545,custo:6.5},
{cod:37,nome:'BONE TIME CAP',sis:7836,cnt:3984,custo:12},
{cod:39,nome:'BONE TRUCK GLX',sis:1689,cnt:1784,custo:16.5},
{cod:40,nome:'BONE TRUCK INFANTIL GLX',sis:1051,cnt:798,custo:12},
{cod:43,nome:'CAMISA DRI-FIT',sis:92,cnt:98,custo:12.5},
{cod:45,nome:'CAMISA PERUANA',sis:74,cnt:73,custo:30},
{cod:47,nome:'CAMISA UBER MOTO',sis:213,cnt:199,custo:16.5},
{cod:51,nome:'CHAPEU CAMUCA',sis:7,cnt:1,custo:11.5},
{cod:52,nome:'CHAPEU CARANDA',sis:67,cnt:63,custo:9.5},
{cod:53,nome:'CHAPEU CATAOVO',sis:235,cnt:251,custo:15.5},
{cod:55,nome:'CHAPEU COURO',sis:49,cnt:49,custo:27},
{cod:59,nome:'CHAPEU LAMPIAO',sis:389,cnt:392,custo:42},
{cod:60,nome:'CHAPEU MALANDRINHO',sis:298,cnt:299,custo:8},
{cod:62,nome:'CHAPEU PANAMA',sis:189,cnt:209,custo:15},
{cod:63,nome:'CHAPEU PESCADOR',sis:1317,cnt:1384,custo:6.5},
{cod:64,nome:'CHAPEU PESCADOR GLX',sis:123,cnt:119,custo:8.9},
{cod:65,nome:'CHAPEU PRAIA GLX',sis:221,cnt:228,custo:8.9},
{cod:66,nome:'CINTO GLX A',sis:1252,cnt:1309,custo:9},
{cod:68,nome:'MANGUITO',sis:2143,cnt:2134,custo:2.2},
{cod:72,nome:'MEIA ALTOMAX LONGA (C/12)',sis:111,cnt:112,custo:23},
{cod:73,nome:'MEIA ALTOMAX CURTA (C/12)',sis:35,cnt:34,custo:20},
{cod:80,nome:'PANO DE PRATO (C/12)',sis:330,cnt:318,custo:19},
{cod:81,nome:'PELUCIA G',sis:415,cnt:391,custo:12.5},
{cod:83,nome:'POCHETE GLX',sis:404,cnt:408,custo:14.9},
{cod:85,nome:'PORTA CHUTEIRA OVAL',sis:205,cnt:177,custo:14},
{cod:86,nome:'PORTA CHUTEIRA QUADRADA',sis:183,cnt:184,custo:12},
{cod:87,nome:'SAQUINHO COSTA',sis:2252,cnt:2341,custo:3.8},
{cod:92,nome:'TOUCA GLX',sis:68,cnt:50,custo:7.9},
{cod:93,nome:'VISEIRA',sis:159,cnt:158,custo:14},
{cod:94,nome:'VISEIRA ACRILICO GLX',sis:128,cnt:110,custo:1},
{cod:97,nome:'VISEIRA GLX',sis:200,cnt:163,custo:6},
{cod:98,nome:'BONE BEBEZINHO',sis:895,cnt:854,custo:10.9},
{cod:101,nome:'CHAPEU BUCKTS LISO',sis:2048,cnt:2084,custo:5},
{cod:102,nome:'BONE PINTADO PRIMEIRA LINHA',sis:1751,cnt:1732,custo:12},
{cod:105,nome:'POCHETE BASICA GLX',sis:164,cnt:152,custo:7.9},
{cod:107,nome:'BOLSA TRANVERSAL GLX',sis:170,cnt:163,custo:13.9},
{cod:108,nome:'CHAPEU BUCKST INFANTIL',sis:280,cnt:213,custo:5},
{cod:109,nome:'CHAPEU BUCKST BEBE',sis:99,cnt:59,custo:9.9},
{cod:110,nome:'CHAPEU BUCKST BEBE GLX',sis:80,cnt:217,custo:8.9},
{cod:115,nome:'CHAPEU PESCADOR SEM SAIA',sis:512,cnt:505,custo:6},
{cod:116,nome:'CHAPEU DUPLA FACE GLX',sis:336,cnt:310,custo:8.9},
{cod:123,nome:'BONE TRUCK GOSPEL',sis:78,cnt:58,custo:13.4},
{cod:140,nome:'CARTEIRA MASCULINA PREMIUM',sis:191,cnt:215,custo:10},
{cod:141,nome:'CARTEIRA TELES',sis:544,cnt:601,custo:10},
{cod:144,nome:'CHAVEIRO M',sis:695,cnt:674,custo:2.5},
{cod:149,nome:'BONE MARCA SIMPLES',sis:414,cnt:337,custo:7.5},
{cod:151,nome:'BONE GLX',sis:222,cnt:245,custo:9.9},
{cod:152,nome:'CINTO GLX B',sis:90,cnt:106,custo:18},
{cod:153,nome:'BONE CIRIO TACTEL',sis:1497,cnt:1532,custo:5},
{cod:154,nome:'PORTA CHUTEIRA TRIANGULAR',sis:265,cnt:280,custo:15},
{cod:155,nome:'BOLSA ACADEMIA P',sis:83,cnt:81,custo:20},
{cod:156,nome:'BANDEIRAS CLUBES',sis:255,cnt:245,custo:18},
{cod:158,nome:'BOLSA QUADRADA BAU',sis:93,cnt:90,custo:25},
{cod:159,nome:'TOUCA DE TIMES',sis:229,cnt:268,custo:9},
{cod:160,nome:'BONE GLX INFANTIL',sis:226,cnt:269,custo:11.9},
{cod:163,nome:'BONE TELADO CAP',sis:3945,cnt:5031,custo:11},
{cod:165,nome:'BONE LACKPARD',sis:1253,cnt:1252,custo:22},
{cod:168,nome:'POCHETE BRACO',sis:103,cnt:103,custo:8.9},
{cod:171,nome:'CHAPEU PALHA COMUN',sis:17,cnt:5,custo:4},
{cod:175,nome:'BONE TELA LISO CAP',sis:903,cnt:903,custo:7},
{cod:181,nome:'SHORT DRI-FIT',sis:171,cnt:168,custo:13.5},
{cod:202,nome:'CHAPEU GUSTAVO LIMA',sis:66,cnt:67,custo:60},
{cod:801,nome:'BOLSA GOLD G',sis:100,cnt:98,custo:38},
{cod:807,nome:'CARTEIRA FEMININA',sis:30,cnt:27,custo:10},
{cod:809,nome:'CINTO COUNTRY FEMININO',sis:90,cnt:87,custo:10},
{cod:810,nome:'BOLSA XADREZ DE LADO',sis:114,cnt:113,custo:13},
{cod:811,nome:'BOLSA XADREZ',sis:109,cnt:93,custo:12},
{cod:812,nome:'PORTA CHUTEIRA XADREZ',sis:27,cnt:25,custo:18},
{cod:813,nome:'BONE CLASSIC',sis:635,cnt:552,custo:18},
{cod:814,nome:'BONE CAMPANHA',sis:654,cnt:644,custo:18},
];
inv.forEach(i=>{i.dif=i.cnt-i.sis;i.imp=Math.abs(i.dif)*i.custo;i.st=i.dif<0?'falta':i.dif>0?'sobra':'ok'});
const faltas=inv.filter(i=>i.st==='falta').sort((a,b)=>b.imp-a.imp);
const sobras=inv.filter(i=>i.st==='sobra').sort((a,b)=>b.imp-a.imp);
/* ── CHART DEFAULTS ── */
Chart.defaults.color='#7d8fa1';
Chart.defaults.font.family="'DM Sans',sans-serif";
Chart.defaults.font.size=11;
const TT={backgroundColor:'#161b22',borderColor:'#21262d',borderWidth:1,titleColor:'#e6edf3',bodyColor:'#7d8fa1',padding:10,cornerRadius:2};
const GX={grid:{color:'#21262d'},ticks:{color:'#4a5968'}};
const brl=v=>'R$ '+v.toLocaleString('pt-BR',{minimumFractionDigits:2,maximumFractionDigits:2});
const lbl=s=>s.length>22?s.slice(0,22)+'…':s;
function bar(id,labels,vals,colors,horiz=true){
return new Chart(document.getElementById(id),{
type:'bar',
data:{labels,datasets:[{data:vals,backgroundColor:colors,borderWidth:0,borderRadius:2}]},
options:{
responsive:true,indexAxis:horiz?'y':'x',
plugins:{legend:{display:false},tooltip:{...TT,callbacks:{label:c=>brl(c.raw)}}},
scales:horiz?{x:{...GX,ticks:{...GX.ticks,callback:v=>v>=1000?(v/1000).toFixed(0)+'k':v}},y:{...GX}}
:{x:{...GX},y:{...GX,ticks:{...GX.ticks,callback:v=>v>=1000?(v/1000).toFixed(0)+'k':v}}}
}
});
}
function donut(id,labels,vals,colors){
return new Chart(document.getElementById(id),{
type:'doughnut',
data:{labels,datasets:[{data:vals,backgroundColor:colors,borderColor:'#161b22',borderWidth:2}]},
options:{responsive:true,cutout:'55%',plugins:{legend:{display:true,position:'right',labels:{color:'#7d8fa1',padding:6,font:{size:9},boxWidth:10}},tooltip:{...TT,callbacks:{label:c=>brl(c.raw)}}}}
});
}
/* BUILD CHARTS */
new Chart(document.getElementById('cComp'),{
type:'bar',
data:{
labels:['Total Faltas','Total Sobras','Prejuízo Líquido'],
datasets:[{
data:[60488.70,19577.30,40911.40],
backgroundColor:['rgba(224,92,82,.75)','rgba(61,191,114,.75)','rgba(212,170,53,.75)'],
borderWidth:0,borderRadius:2
}]
},
options:{responsive:true,plugins:{legend:{display:false},tooltip:{...TT,callbacks:{label:c=>brl(c.raw)}}},scales:{x:{...GX},y:{...GX,ticks:{...GX.ticks,callback:v=>'R$'+(v/1000).toFixed(0)+'k'}}}}
});
new Chart(document.getElementById('cSt'),{
type:'doughnut',
data:{
labels:['Sem Divergência','Com Falta','Com Sobra','Zerado'],
datasets:[{
data:[62,45,38,25],
backgroundColor:['rgba(68,132,184,.7)','rgba(224,92,82,.7)','rgba(61,191,114,.7)','rgba(74,89,104,.4)'],
borderColor:'#161b22',borderWidth:2
}]
},
options:{responsive:true,cutout:'65%',plugins:{legend:{display:true,position:'bottom',labels:{color:'#7d8fa1',padding:8,font:{size:10},boxWidth:10}},tooltip:{...TT}}}
});
const tf6=faltas.slice(0,6),ts5=sobras.slice(0,5);
bar('cTF',tf6.map(i=>lbl(i.nome)),tf6.map(i=>i.imp),tf6.map((_,k)=>k===0?'rgba(224,92,82,.9)':'rgba(224,92,82,.5)'));
bar('cTS',ts5.map(i=>lbl(i.nome)),ts5.map(i=>i.imp),ts5.map((_,k)=>k===0?'rgba(61,191,114,.9)':'rgba(61,191,114,.5)'));
const f8=faltas.slice(0,8),s8=sobras.slice(0,8);
bar('cFB',f8.map(i=>lbl(i.nome)),f8.map(i=>i.imp),f8.map((_,k)=>k===0?'rgba(224,92,82,.9)':'rgba(224,92,82,.5)'));
donut('cFP',f8.map(i=>i.nome.slice(0,15)),f8.map(i=>i.imp),['#c0392b','#a83224','#902b1d','#782416','#601d0f','rgba(224,92,82,.5)','rgba(224,92,82,.3)','rgba(224,92,82,.15)']);
bar('cSB',s8.map(i=>lbl(i.nome)),s8.map(i=>i.imp),s8.map((_,k)=>k===0?'rgba(61,191,114,.9)':'rgba(61,191,114,.5)'));
donut('cSP',s8.map(i=>i.nome.slice(0,15)),s8.map(i=>i.imp),['#27ae60','#228e50','#1d6e40','#184e30','#132e20','rgba(61,191,114,.5)','rgba(61,191,114,.3)','rgba(61,191,114,.15)']);
new Chart(document.getElementById('cRad'),{
type:'radar',
data:{
labels:['Redução\nde Erros','Velocidade\nAuditoria','Confiab.\nDados','Controle\nFurtos','Gestão\nCompras'],
datasets:[
{label:'Situação Atual',data:[15,10,20,15,25],backgroundColor:'rgba(224,92,82,.08)',borderColor:'rgba(224,92,82,.6)',borderWidth:1.5,pointBackgroundColor:'rgba(224,92,82,.8)',pointRadius:3},
{label:'Após Plano',data:[90,85,95,70,88],backgroundColor:'rgba(61,191,114,.08)',borderColor:'rgba(61,191,114,.6)',borderWidth:1.5,pointBackgroundColor:'rgba(61,191,114,.8)',pointRadius:3}
]
},
options:{
responsive:true,
plugins:{
legend:{display:true,position:'bottom',labels:{color:'#7d8fa1',padding:8,font:{size:10}}},
tooltip:{...TT}
},
scales:{r:{grid:{color:'#21262d'},angleLines:{color:'#21262d'},pointLabels:{color:'#4a5968',font:{size:9}},ticks:{display:false},suggestedMin:0,suggestedMax:100}}
}
});
/* ── TABLES ── */
const sev=v=>v>=10000?'<span class="badge br">CRÍTICO</span>':v>=2000?'<span class="badge ba">ALTO</span>':v>=500?'<span class="badge bb">MÉDIO</span>':'<span class="badge bk">BAIXO</span>';
function buildF(){
document.getElementById('bF').innerHTML=faltas.map(i=>`
<tr>
<td>${i.nome}</td>
<td class="mono">${i.sis.toLocaleString('pt-BR')}</td>
<td class="mono">${i.cnt.toLocaleString('pt-BR')}</td>
<td class="mono cr">${i.dif.toLocaleString('pt-BR')}</td>
<td class="mono cm">R$${i.custo.toFixed(2)}</td>
<td class="mono ca">${brl(i.imp)}</td>
<td>${sev(i.imp)}</td>
</tr>`).join('');
document.getElementById('cF').textContent=faltas.length+' itens com falta';
}
function buildS(){
document.getElementById('bS').innerHTML=sobras.map(i=>`
<tr>
<td>${i.nome}</td>
<td class="mono">${i.sis.toLocaleString('pt-BR')}</td>
<td class="mono">${i.cnt.toLocaleString('pt-BR')}</td>
<td class="mono cg">+${i.dif.toLocaleString('pt-BR')}</td>
<td class="mono cm">R$${i.custo.toFixed(2)}</td>
<td class="mono cg">${brl(i.imp)}</td>
</tr>`).join('');
document.getElementById('cS').textContent=sobras.length+' itens com sobra';
}
let ff='todos',fs='';
function buildI(){
const d=inv.filter(i=>{
const mf=ff==='todos'||i.st===ff;
const ms=i.nome.toLowerCase().includes(fs.toLowerCase())||String(i.cod).includes(fs);
return mf&&ms;
});
const badge=st=>st==='falta'?'<span class="badge br">▼ FALTA</span>':st==='sobra'?'<span class="badge bg">▲ SOBRA</span>':'<span class="badge bk">OK</span>';
document.getElementById('bI').innerHTML=d.map(i=>{
const ds=i.dif===0?'—':(i.dif>0?'+':'')+i.dif.toLocaleString('pt-BR');
const dc=i.dif<0?'cr':i.dif>0?'cg':'cm';
return`<tr>
<td class="mono cm">${i.cod}</td>
<td>${i.nome}</td>
<td class="mono">${i.sis.toLocaleString('pt-BR')}</td>
<td class="mono">${i.cnt!==null?i.cnt.toLocaleString('pt-BR'):'—'}</td>
<td class="mono ${dc}">${ds}</td>
<td class="mono cm">R$${i.custo.toFixed(2)}</td>
<td class="mono ${i.dif!==0?(i.dif<0?'ca':'cg'):'cm'}">${i.dif!==0?brl(i.imp):'—'}</td>
<td>${badge(i.st)}</td>
</tr>`;
}).join('');
document.getElementById('cI').textContent=d.length+' de '+inv.length+' itens';
}
function setF(f){
ff=f;
[{id:'bT',k:'todos'},{id:'bFa',k:'falta'},{id:'bSo',k:'sobra'},{id:'bOk',k:'ok'}].forEach(x=>{
document.getElementById(x.id).classList.toggle('on',x.k===f);
});
buildI();
}
function filterInv(){fs=document.getElementById('srch').value;buildI()}
/* ── SORT ── */
const SS={};
function srt(tid,col){
const t=document.getElementById(tid);
const tb=t.querySelector('tbody');
const rows=[...tb.querySelectorAll('tr')];
const k=tid+'_'+col;
const asc=SS[k]=!SS[k];
rows.sort((a,b)=>{
const av=a.cells[col]?.textContent.trim().replace(/[R$.\s▼▲✓ ]/g,'').replace(',','')||'';
const bv=b.cells[col]?.textContent.trim().replace(/[R$.\s▼▲✓ ]/g,'').replace(',','')||'';
const an=parseFloat(av),bn=parseFloat(bv);
if(!isNaN(an)&&!isNaN(bn))return asc?an-bn:bn-an;
return asc?av.localeCompare(bv,'pt-BR'):bv.localeCompare(av,'pt-BR');
});
t.querySelectorAll('th').forEach(th=>th.classList.remove('sa','sd'));
t.querySelectorAll('th')[col].classList.add(asc?'sa':'sd');
rows.forEach(r=>tb.appendChild(r));
}
/* ── RESPONSIVE ── */
function fixRisk(){const g=document.querySelector('.risk-grid');if(!g)return;g.style.gridTemplateColumns=window.innerWidth<600?'1fr':'1fr 1fr'}
window.addEventListener('resize',fixRisk);fixRisk();
/* ── INIT ── */
buildF();buildS();buildI();
</script>
</body>
</html>