<script lang="ts">
export let consumed: number | undefined = undefined;
export let budget: number | undefined = undefined;
export let ariaLabel: string | undefined = undefined;
function fmtTokens(n: number): string {
if (n >= 1_000_000) {
const m = n / 1_000_000;
return Number.isInteger(m) ? `${m}m` : `${m.toFixed(1)}m`;
}
if (n >= 1_000) {
const k = n / 1_000;
return Number.isInteger(k) ? `${k}k` : `${Math.round(k)}k`;
}
return String(n);
}
$: hasReceipt =
typeof consumed === "number" &&
typeof budget === "number" &&
!Number.isNaN(consumed) &&
!Number.isNaN(budget) &&
budget > 0;
// As context fills, the battery drains: full context = empty battery
$: fractionRemaining = hasReceipt ? Math.max(0, Math.min(1, 1 - (consumed! / budget!))) : 0;
$: remainingCells = !hasReceipt
? 0
: fractionRemaining > 0.75
? 4
: fractionRemaining > 0.5
? 3
: fractionRemaining > 0.25
? 2
: fractionRemaining > 0
? 1
: 0;
// Colour by remaining: >=2 cells var(--ok), exactly 1 var(--warn), 0 var(--err)
$: color = !hasReceipt
? "var(--fg-mute)"
: remainingCells >= 2
? "var(--ok)"
: remainingCells === 1
? "var(--warn)"
: "var(--err)";
$: explicitLabel = ariaLabel ?? ($$props["aria-label"] as string | undefined);
$: computedLabel = explicitLabel ?? (
hasReceipt
? `context ${fmtTokens(consumed!)} of ${fmtTokens(budget!)} tokens used`
: "context budget unknown"
);
</script>
<svg
class="battery"
viewBox="0 0 32 16"
width="32"
height="16"
role="img"
aria-label={computedLabel}
style="--battery-color: {color};"
>
<!-- Outer case -->
<rect
class="case"
x="1"
y="1"
width="26"
height="14"
rx="2.5"
fill="none"
stroke="var(--battery-color)"
stroke-width="1.2"
/>
<!-- Terminal nub -->
<rect
class="nub"
x="28"
y="5"
width="2.5"
height="6"
rx="1"
fill="var(--battery-color)"
/>
<!-- 4 cells inside (rendered only when receipt exists) -->
{#if hasReceipt}
{#each [0, 1, 2, 3] as idx}
<!-- Empty slot background for glanceability without relying on colour alone -->
<rect
class="slot"
x={3.5 + idx * 5.5}
y="3"
width="4"
height="10"
rx="1"
fill="var(--battery-color)"
fill-opacity="0.15"
/>
{#if idx < remainingCells}
<!-- Filled cell -->
<rect
class="cell"
x={3.5 + idx * 5.5}
y="3"
width="4"
height="10"
rx="1"
fill="var(--battery-color)"
/>
{/if}
{/each}
{/if}
</svg>
<style>
.battery {
display: inline-block;
vertical-align: middle;
flex-shrink: 0;
}
</style>