Capacity Stack
A stack of labelled buckets that fills a fixed-size track. Each bucket carries an explicit sizeGb and an optional tone; the track sizes to capacityGb (when given) or to the sum of the buckets otherwise. When the buckets exceed the capacity, the overflow is drawn as a trailing cb-error segment so the gap is read by length, not by inferred ratio. Vertical orientation stacks bottom-up like a memory tank filling; horizontal stacks left-to-right like a budget bar.
Capacity stack. Weights (fp16): 140 GiB; Gradients (fp16): 140 GiB; Optimizer (Adam fp32): 280 GiB; Activations: 80.0 GiB. Total: 640 GiB. Capacity: 80.0 GiB, over by 560 GiB.
Capacity stack640 GiB / 80.0 GiB
- Weights (fp16)140 GiB
- Gradients (fp16)140 GiB
- Optimizer (Adam fp32)280 GiB
- Activations80.0 GiB
- over560 GiB
Customize
Buckets (GiB)
140 GiB
140 GiB
280 GiB
80 GiB
Device
80 GiB
vertical
Display
Installation
npx shadcn@latest add https://craftbits.dev/r/capacity-stack.jsonUsage
import { CapacityStack } from "@craft-bits/core";
<CapacityStack
buckets={[
{ id: "weights", label: "Weights", sizeGb: 140, tone: "accent" },
{ id: "grads", label: "Gradients", sizeGb: 140, tone: "warning" },
{ id: "optim", label: "Optimizer", sizeGb: 280, tone: "success" },
{ id: "acts", label: "Activations", sizeGb: 80 },
]}
capacityGb={80}
/>Switch to a horizontal budget bar:
<CapacityStack buckets={buckets} capacityGb={80} orientation="horizontal" />Hide labels when you only want the bar:
<CapacityStack buckets={buckets} capacityGb={80} showLabels={false} />Understanding the component
- One track, many segments. Each bucket is a child
motion.spanwhoseheight(vertical) orwidth(horizontal) animates to its share of the track. The track itself is a single rounded box. capacityGbsizes the track. When provided, the segments are normalised againstcapacityGb, so the visible length of every bucket reflects its share of the budget, not of the sum. DropcapacityGband the track sizes to the sum.- Overflow segment. When
sum(sizeGb) > capacityGb, the gap is drawn as a trailingcb-errorsegment with an outlined edge. The header total also flips tocb-errorso the failure mode is unmissable. - Free headroom. When the stack fits, the remaining track stays the muted background colour and the label list adds a
freerow with the gap in GiB. Nofreerow appears when nocapacityGbis given. - Vertical reads bottom-up. Vertical orientation reverses the render order so the first bucket sits at the bottom (memory filling a tank). Horizontal preserves the original order (budget bar reading left-to-right).
SPRINGS.smootheverywhere. Segment sizing animates with the canonical smooth spring, staggered bySTAGGERbetween siblings.prefers-reduced-motion: reducecollapses every spring to an instant swap.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
buckets | readonly CapacityStackBucket[] | required | Labelled segments in render order. |
capacityGb | number | — | Total available capacity in GiB. Drives the track length and the overflow segment. |
orientation | `'vertical' | 'horizontal'` | 'vertical' |
showLabels | boolean | true | Render the labelled bucket list under the bar. |
transition | Transition | SPRINGS.smooth | Spring used for segment-size transitions. |
className | string | — | Merged onto the root via cn(). |
The CapacityStackBucket shape: { id: string; label: string; sizeGb: number; tone?: 'accent' | 'warning' | 'success' | 'error' }.
Accessibility
- The figure is
role="figure"with a hidden summary listing every bucket, the total, the capacity, and the overflow or headroom — screen readers hear the story whenever buckets change. - Segments are
role="presentation"because the underlying figures already convey the meaning textually; the visual bar is decorative once the summary is in place. - Colour is never the only signal — every bucket has a label, a tone swatch, and a GiB readout; the header total flips to
cb-errorand the labels list adds an explicitoverrow when the stack overflows. - Motion respects
prefers-reduced-motion: reduce.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/nn/CapacityStack.tsx). The source was a parameter-count expressivity widget — a 2-param line growing into a 10-param wiggly curve to teach "more parameters = more capacity". The library extract reframes the name around its more common usage: visualising GPU memory capacity (weights, gradients, optimizer state, activations) as a labelled stack of buckets that may or may not fit the device. The pure plotting primitive: buckets in, normalised stack out, with vertical or horizontal orientation, motion-library springs, and an overflow segment when the stack exceedscapacityGb.