diff --git a/app/main.py b/app/main.py
index ee9e700..9dfb631 100644
--- a/app/main.py
+++ b/app/main.py
@@ -523,7 +523,7 @@ PAGE_HTML = """
-
+
—
credits left (never expire)
@@ -599,8 +599,11 @@ async function load() {
const pct = balance > 0 ? Math.min(100, (spend / balance) * 100) : 0;
// Two buckets: monthly allowance (resets) + purchased credits (never expire).
+ // Balance view shows credits REMAINING (purchased minus what this cycle's
+ // overspend already drew); the all-time figure is d.credits (total bought).
const allowance = d.allowance ?? 15;
- const credits = d.credits ?? 0;
+ const creditsTotal = d.credits ?? 0;
+ const creditsLeft = d.credits_remaining ?? creditsTotal;
const spentThisCycle = Math.min(spend, allowance);
const allowanceLeft = Math.max(0, allowance - spentThisCycle);
@@ -608,7 +611,7 @@ async function load() {
$('of').textContent = 'of ' + fmtMoney(balance) + ' current balance used';
$('remaining').textContent = fmtMoney(remaining);
$('allowance').textContent = fmtMoney(allowanceLeft);
- $('credits').textContent = fmtMoney(credits);
+ $('credits').textContent = fmtMoney(creditsLeft);
$('fill').style.width = pct + '%';
$('fill').className = 'fill' + (pct > 80 ? ' warn' : '');
@@ -617,7 +620,7 @@ async function load() {
const d2 = new Date(d.reset_at);
const opts = { year: 'numeric', month: 'long', day: 'numeric' };
let meta = 'Shared across chat and API · Allowance renews ' + d2.toLocaleDateString(undefined, opts);
- if (credits > 0) meta += ' · Credits carry over and never expire';
+ if (creditsTotal > 0) meta += ' · Credits never expire (' + fmtMoney(creditsTotal) + ' purchased all-time)';
$('meta').textContent = meta + '.';
}