From 6bd97a2a03f1e0f711d0194d5eb42be9eb5a993f Mon Sep 17 00:00:00 2001 From: Zac Gaetano Date: Mon, 18 May 2026 11:05:30 -0400 Subject: [PATCH] feat(meme): Token Pricing page with usage chart + AMPP-style Z-AMPP SVG wordmark on home + Tokens tile/nav everywhere --- services/web-ui/public/capture.html | 1 + services/web-ui/public/edit.html | 1 + services/web-ui/public/home.html | 28 ++++- services/web-ui/public/index.html | 1 + services/web-ui/public/jobs.html | 1 + services/web-ui/public/projects.html | 1 + services/web-ui/public/recorders.html | 1 + services/web-ui/public/tokens.html | 143 ++++++++++++++++++++++++++ services/web-ui/public/upload.html | 1 + 9 files changed, 177 insertions(+), 1 deletion(-) diff --git a/services/web-ui/public/capture.html b/services/web-ui/public/capture.html index 6017a32..5b1d15f 100644 --- a/services/web-ui/public/capture.html +++ b/services/web-ui/public/capture.html @@ -209,6 +209,7 @@ Jobs + Tokens Editor diff --git a/services/web-ui/public/edit.html b/services/web-ui/public/edit.html index a337f5a..8590ea8 100644 --- a/services/web-ui/public/edit.html +++ b/services/web-ui/public/edit.html @@ -322,6 +322,7 @@ Capture Editor Jobs + Tokens diff --git a/services/web-ui/public/home.html b/services/web-ui/public/home.html index 21f9f49..b6b76b1 100644 --- a/services/web-ui/public/home.html +++ b/services/web-ui/public/home.html @@ -69,6 +69,7 @@ 0%, 100% { opacity: 0.85; transform: scale(1); } 50% { opacity: 1; transform: scale(1.1); } } + .home-wordmark-svg { width: min(380px, 70vw); height: auto; filter: drop-shadow(0 16px 30px oklch(35% 0.18 266 / 0.45)); margin-bottom: -10px; } .home-wordmark { font-size: 36px; font-weight: 700; letter-spacing: -0.02em; @@ -213,7 +214,16 @@ Zac in hardhat -

Z-AMPP

+ + + + + + + + + Z-AMPP +
Please select an option below to get started
@@ -357,6 +367,21 @@
Track proxy generation, thumbnails, and AMPP folder sync as they run.
+ + +
Tokens
+
+ + + + + + + +  burning +
+
Token-metered pricing parody. Click for a giggle. (You actually pay $0.)
+
@@ -402,6 +427,7 @@ setText('jobCount', arr.length); setText('ingestCount', arr.filter(x => (x.type || '').toLowerCase().includes('proxy')).length || arr.length); } + const tb = document.getElementById('tokenBurn'); if (tb) { tb.textContent = (14000 + Math.round(Math.random() * 8000)).toLocaleString(); } } catch (_) { /* leave dashes */ } } loadStats(); diff --git a/services/web-ui/public/index.html b/services/web-ui/public/index.html index 6d7fb6a..dba95b1 100644 --- a/services/web-ui/public/index.html +++ b/services/web-ui/public/index.html @@ -343,6 +343,7 @@ Jobs + Tokens Editor diff --git a/services/web-ui/public/jobs.html b/services/web-ui/public/jobs.html index f5560cd..181ea11 100644 --- a/services/web-ui/public/jobs.html +++ b/services/web-ui/public/jobs.html @@ -388,6 +388,7 @@ Jobs + Tokens Editor diff --git a/services/web-ui/public/projects.html b/services/web-ui/public/projects.html index ddd0d91..38a6859 100644 --- a/services/web-ui/public/projects.html +++ b/services/web-ui/public/projects.html @@ -262,6 +262,7 @@ Recorders Capture Jobs + Tokens Editor diff --git a/services/web-ui/public/recorders.html b/services/web-ui/public/recorders.html index 651cb26..e6fd524 100644 --- a/services/web-ui/public/recorders.html +++ b/services/web-ui/public/recorders.html @@ -154,6 +154,7 @@ Jobs + Tokens Editor diff --git a/services/web-ui/public/tokens.html b/services/web-ui/public/tokens.html index a60d78f..a387436 100644 --- a/services/web-ui/public/tokens.html +++ b/services/web-ui/public/tokens.html @@ -268,6 +268,50 @@ .tok-row > :nth-child(4), .tok-row > :nth-child(5) { display: none; } .tok-title { font-size: 30px; } } + + /* ─ Token burn chart ─ */ + .tok-chart { + background: oklch(11% 0.020 220 / 0.7); + border: 1px solid oklch(35% 0.06 215 / 0.5); + border-radius: 12px; + padding: 20px 22px 22px; + backdrop-filter: blur(6px); + } + .tok-chart-stats { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); + gap: 12px; + margin-bottom: 18px; + } + .tok-stat { + display: flex; flex-direction: column; gap: 2px; + padding: 10px 12px; + background: oklch(8% 0.015 220 / 0.7); + border: 1px solid oklch(35% 0.06 215 / 0.3); + border-radius: 8px; + } + .tok-stat-label { font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-tertiary); } + .tok-stat-value { font-family: var(--font-mono); font-size: 20px; font-weight: 700; color: var(--text-primary); letter-spacing: -0.01em; } + .tok-stat-delta { font-size: 10px; font-weight: 600; color: var(--text-tertiary); letter-spacing: 0.04em; } + .tok-stat-delta.hot { color: oklch(70% 0.18 25); } + .tok-stat-delta.cold { color: oklch(70% 0.14 145); } + .tok-chart-frame { + position: relative; + background: oklch(8% 0.015 220 / 0.7); + border: 1px solid oklch(35% 0.06 215 / 0.3); + border-radius: 8px; + padding: 16px; + } + .tok-chart-svg { width: 100%; height: 260px; display: block; } + .tok-chart-legend { + display: flex; flex-wrap: wrap; gap: 18px; + margin-top: 10px; + font-size: 11px; color: var(--text-secondary); + letter-spacing: 0.04em; + } + .tok-chart-legend span { display: inline-flex; align-items: center; gap: 6px; } + .tok-chart-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; } + @@ -478,6 +522,29 @@ + +
+ Current Token Burn + Last 14 days · nightly true-up · TVM applied +
+
+
+
MTD burn+0%
+
Forecast EOMover plan
+
TVM (live)stable
+
Peak drawWed
+
+
+ +
+ Ingest + Recorders + Render + Overage +
+
+
+
@@ -557,6 +624,82 @@ } document.querySelectorAll('.tok-calc-field input').forEach(i => i.addEventListener('input', calc)); calc(); + + async function renderBurnChart() { + let realJobs = 0, realAssets = 0; + try { + const [jRes, aRes] = await Promise.all([ + fetch('/api/v1/jobs', { credentials: 'include' }), + fetch('/api/v1/assets?limit=1', { credentials: 'include' }), + ]); + if (jRes.ok) realJobs = (await jRes.json()).length; + if (aRes.ok) realAssets = (await aRes.json()).total || 0; + } catch (_) {} + const N = 14; + const days = []; + const today = new Date(); + for (let i = N - 1; i >= 0; i--) { + const d = new Date(today); d.setDate(d.getDate() - i); + days.push(d); + } + function rng(seed) { let x = Math.sin(seed) * 10000; return x - Math.floor(x); } + const series = days.map((d, i) => { + const baseline = 8000 + realAssets * 18 + realJobs * 12; + const wk = (d.getDay() === 0 || d.getDay() === 6) ? 0.55 : 1.0; + const wave = 1 + 0.45 * Math.sin(i * 0.9) + 0.18 * Math.cos(i * 1.7); + const noise = 0.8 + 0.4 * rng(i * 13 + 7); + const total = Math.round(baseline * wk * wave * noise); + const ingest = Math.round(total * (0.35 + 0.05 * rng(i * 3 + 1))); + const recorders = Math.round(total * (0.30 + 0.04 * rng(i * 5 + 2))); + const render = Math.round(total * (0.20 + 0.04 * rng(i * 7 + 3))); + const overage = Math.max(0, total - ingest - recorders - render); + return { d, ingest, recorders, render, overage, total }; + }); + const max = Math.max(...series.map(s => s.total)); + const W = 800, H = 220, P = 28; + const bw = (W - P * 2) / N; + const layers = [ + { key: 'ingest', color: 'oklch(70% 0.18 200)' }, + { key: 'recorders', color: 'oklch(62% 0.15 145)' }, + { key: 'render', color: 'oklch(70% 0.18 80)' }, + { key: 'overage', color: 'oklch(62% 0.22 25)' }, + ]; + const bars = series.map((s, i) => { + const x = P + i * bw + 4; + let yAcc = H - P; + const stack = layers.map(l => { + const v = s[l.key] || 0; + const h = (v / max) * (H - P * 2); + yAcc -= h; + return ''; + }).join(''); + const label = s.d.toLocaleDateString('en', { month: 'short', day: 'numeric' }); + const lbl = i % 2 === 0 ? '' + label + '' : ''; + return stack + lbl; + }).join(''); + let grid = ''; + for (let k = 0; k <= 4; k++) { + const y = P + (H - P * 2) * (k / 4); + grid += ''; + const tick = Math.round(max * (1 - k / 4)); + grid += '' + tick.toLocaleString() + ''; + } + document.getElementById('burnChart').innerHTML = grid + bars; + const mtd = series.reduce((a, s) => a + s.total, 0); + const eom = Math.round(mtd * 2.3); + const peakIdx = series.reduce((max, s, i, arr) => s.total > arr[max].total ? i : max, 0); + const tvm = (0.92 + 0.6 * rng(Date.now() / 60000 | 0)).toFixed(2); + document.getElementById('statMtd').textContent = mtd.toLocaleString(); + document.getElementById('statMtdDelta').textContent = '+' + Math.round(rng(1) * 40 + 15) + '% vs prior period'; + document.getElementById('statEom').textContent = eom.toLocaleString(); + document.getElementById('statEomDelta').textContent = '+340% over plan'; + document.getElementById('statTvm').textContent = tvm + 'x'; + document.getElementById('statTvmTrend').textContent = parseFloat(tvm) > 1.2 ? 'spiking' : 'stable'; + document.getElementById('statPeak').textContent = series[peakIdx].total.toLocaleString(); + document.getElementById('statPeakDay').textContent = series[peakIdx].d.toLocaleDateString('en', { weekday: 'short' }); + } + renderBurnChart(); + diff --git a/services/web-ui/public/upload.html b/services/web-ui/public/upload.html index 6f842f1..3ffbbfc 100644 --- a/services/web-ui/public/upload.html +++ b/services/web-ui/public/upload.html @@ -180,6 +180,7 @@ Jobs + Tokens Editor