restockiq / app /static /index.html
RV302001's picture
UI v2 (self-explanatory) + API tests + caching + lifespan
0b9787b
Raw
History Blame Contribute Delete
7.22 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RestockIQ — never run out, never overstock</title>
<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=Fraunces:opsz,wght@9..144,600;9..144,900&family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/style.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.9/dist/chart.umd.min.js"></script>
</head>
<body>
<header class="topbar">
<div class="wordmark">Restock<span>IQ</span></div>
<a class="apilink" href="/docs" target="_blank" rel="noopener">API docs ↗</a>
</header>
<!-- ============ HERO: the site explains itself ============ -->
<section class="hero">
<h1>Never run out.<br>Never overstock.</h1>
<p class="hero-sub">
Running a store means guessing how much of each product to reorder.
Guess low — empty shelves and lost sales. Guess high — money frozen in boxes.
<b>RestockIQ studies your sales history and replaces the guess with a number.</b>
</p>
<ol class="hero-steps">
<li><b>Pick</b> a store and a product below</li>
<li><b>Tell us</b> how many units are on your shelf</li>
<li><b>Get</b> the exact quantity to order — and when</li>
</ol>
</section>
<main>
<!-- ============ CONTROLS ============ -->
<section class="card controls">
<div class="field">
<label for="store">Store</label>
<select id="store"></select>
</div>
<div class="field">
<label for="item">Product</label>
<select id="item"></select>
</div>
<div class="field">
<label for="inventory">Units on your shelf</label>
<div class="stepper">
<button type="button" data-step="-1" data-for="inventory" aria-label="decrease"></button>
<input type="number" id="inventory" value="20" min="0" step="1">
<button type="button" data-step="1" data-for="inventory" aria-label="increase">+</button>
</div>
</div>
<div class="field">
<label for="service">Protection level
<button class="whatis" data-tip="How rarely you're willing to run out. High = roughly 19 weeks in 20 you never hit an empty shelf, at the cost of holding a little more stock.">?</button>
</label>
<select id="service">
<option value="0.90">Standard — 90%</option>
<option value="0.95" selected>High — 95%</option>
<option value="0.99">Maximum — 99%</option>
</select>
</div>
<div class="field">
<label for="leadtime">Delivery time (days)
<button class="whatis" data-tip="How long your supplier takes to deliver after you order. The plan covers this gap.">?</button>
</label>
<div class="stepper">
<button type="button" data-step="-1" data-for="leadtime" aria-label="decrease"></button>
<input type="number" id="leadtime" value="7" min="1" max="28" step="1">
<button type="button" data-step="1" data-for="leadtime" aria-label="increase">+</button>
</div>
</div>
</section>
<!-- ============ ANSWER + CHART ============ -->
<section class="duo">
<div class="card answer">
<h2 class="eyebrow">What should I do?</h2>
<div id="status-chip" class="chip"></div>
<div class="bignum"><span id="order-qty"></span><span class="unit">units to order</span></div>
<p class="verdict" id="verdict">Loading…</p>
<div class="mathrow" aria-label="how the number is built">
<div class="mathbit"><span class="mval" id="r-sell"></span><span class="mlab">will likely sell before delivery</span></div>
<div class="mathop">+</div>
<div class="mathbit"><span class="mval" id="r-cushion"></span><span class="mlab">cushion for busy days</span></div>
<div class="mathop"></div>
<div class="mathbit"><span class="mval" id="r-have"></span><span class="mlab">already on your shelf</span></div>
</div>
<details class="nerd">
<summary>Under the hood</summary>
<p>Reorder point <b id="n-rop"></b> = lead-time demand + safety stock.
Safety stock <b id="n-ss"></b> = z(<span id="n-sl"></span>) × σ<sub>demand</sub> <b id="n-std"></b> × √lead.
σ comes from the forecast's own P90−P50 spread (÷1.2816) — three global LightGBM
quantile models trained across 30,490 Walmart series.</p>
</details>
</div>
<div class="card chartcard">
<h2 class="eyebrow">How good are our predictions for this product?</h2>
<div class="chartwrap"><canvas id="chart"></canvas></div>
<p class="chart-read">
<b>How to read it:</b> the white line is real daily sales. Left of the marker is
the past. Right of it, the <span class="c-amber">dotted amber line</span> is what we
predicted <i>before</i> seeing those days, and the <span class="c-band">shaded band</span>
is the range we promised sales would stay inside about 8 weeks in 10.
The band hugging the white line = the forecast you can trust.
</p>
</div>
</section>
<!-- ============ STORE-WIDE ACTION LIST ============ -->
<section class="card actioncard">
<h2 class="eyebrow">Your whole store, one glance</h2>
<p class="lede">All 3,049 products in <b id="al-store"></b> ranked by how urgently they need a restock — so Monday morning starts with a list, not a guess.
<span class="assume">(Demo assumes <b id="al-inv">20</b> units on the shelf for every product — change “units on your shelf” above.)</span></p>
<div class="counts" id="al-counts"></div>
<table class="actiontable">
<thead>
<tr><th>Product</th><th>Status</th><th>Order</th><th>Sells / day</th><th>Cushion</th></tr>
</thead>
<tbody id="al-body"></tbody>
</table>
<p class="footnote">Click any row to inspect that product above.</p>
</section>
<!-- ============ PROOF ============ -->
<section class="card proof">
<h2 class="eyebrow">Proof it works</h2>
<p class="lede">We replayed the final 28 days of real sales across all 30,490 products. Two managers, same store: one reorders on gut feel (average sales × delivery days), one follows RestockIQ.</p>
<div class="proofgrid" id="proofgrid"></div>
<p class="footnote" id="proof-note"></p>
</section>
</main>
<footer>
<p>Sales data: real Walmart history, 2011–2016 (M5 dataset, 30,490 product-store series). Shelf counts and delivery times are illustrative inputs — this demo has no live inventory feed. Built with LightGBM quantile models, FastAPI, and Chart.js — no LLM anywhere. <a href="/docs" target="_blank" rel="noopener">REST API docs</a>.</p>
</footer>
<script src="/app.js"></script>
</body>
</html>