Context Window Viz

An interactive visualisation of how a single LLM forward pass actually packs its input. The user's question is the tiny stripe at the bottom; everything above it — system prompt, tool definitions, few-shot examples, retrieved documents, conversation history — has to fit into the same fixed budget. Hover or keyboard-focus any section to surface where it came from, how trusted it is, how long it persists, and a representative snippet. Flip between proportional (accurate) and equal-height (readable) modes to compare scale against legibility.

128K tokens
3.0K
2.0K
1.5K
15K
8.0K
98K free

Hover or focus a section to see details

30K / 128K
23.2% used
Context window: 29,700 of 128,000 tokens used across 6 sections.

This is everything the model sees in a single forward pass. Hover each section to learn what it contains and where it comes from.

Customize
Budget
128,000
440px
Display

Installation

npx shadcn@latest add https://craftbits.dev/r/context-window-viz.json

Usage

import { ContextWindowViz } from "@craft-bits/viz/context-window-viz";
 
<ContextWindowViz />

Bring your own sections:

<ContextWindowViz
  tokenBudget={32_000}
  sections={[
    {
      id: "system",
      label: "System Prompt",
      tokens: 1_800,
      color: "var(--cb-accent)",
      colorMuted: "color-mix(in srgb, var(--cb-accent) 70%, transparent)",
      source: "Developer",
      trustLevel: "Fully trusted",
      lifetime: "Persistent",
      example: "You are an internal support agent...",
    },
    /* … */
  ]}
/>

Subscribe to interaction events:

<ContextWindowViz
  onActiveChange={(section) => {
    /* lift the active section into an external display */
  }}
  onProportionalChange={(p) => {
    /* persist the user's preferred scale mode */
  }}
/>

Understanding the component

  1. The stacked bar. A vertical column where each section occupies a slice. In proportional mode the slice height equals (section.tokens / totalUsed) * barHeight, clamped so even tiny sections stay visible. In equal-height mode every slice gets the same room — useful for reading labels when one section dwarfs the rest.
  2. The free zone. Whatever's left in tokenBudget − totalUsed renders as a muted strip at the bottom, labelled with the remaining token count.
  3. Hover + focus tooltip. Hover takes precedence over keyboard focus. The active section's fill brightens, the legend dot grows, and a tooltip panel surfaces source, trust, lifetime, and a sample snippet. The trust value is colour-coded on three buckets — trusted (success), semi/mixed (warning), untrusted (error).
  4. Token counter. A horizontal progress bar shows totalUsed / tokenBudget with a percentage label. The proportional / equal-height toggle sits alongside.
  5. Insight callout. Once the user views every section or toggles the scale, an insight callout drops below the bar comparing the user-message size to the total used context.
  6. Reduced motion. Under prefers-reduced-motion: reduce, every section resize, tooltip swap, and callout entrance collapses to an instant transition.

Props

PropTypeDefaultDescription
sectionsreadonly ContextWindowVizSection[]6-section anatomyThe sections that fill the bar, top-to-bottom.
tokenBudgetnumber128000Hard upper bound for the context window.
barHeightnumber440Height of the vertical bar in pixels.
defaultProportionalbooleantrueInitial scale mode.
transitionTransitionSPRINGS.smoothOverride the bar spring.
onActiveChange(section) => voidFires when the active section changes (hover or focus).
onProportionalChange(proportional) => voidFires when the scale toggle flips.
classNamestringMerged onto the root via cn().

Accessibility

  • The visualization root is role="figure" with an aria-label summarising current token usage and section count.
  • The horizontal token bar is role="progressbar" with aria-valuemin / aria-valuemax / aria-valuenow reflecting live token usage.
  • Each section is reachable via Tab (role="button", tabIndex={0}) and announces its label, token count, and percentage of used context. Hover and keyboard focus both drive the active state.
  • A polite live region announces the active section's source, trust, and lifetime on every change, and falls back to a budget summary when nothing is hovered or focused.
  • The scale toggle uses aria-pressed and reads as "Switch to equal-height view" / "Switch to proportional view" depending on the current state.
  • Colour is never the only signal — every trust level carries its full text and every section carries its label.
  • Motion respects prefers-reduced-motion: reduce — every section resize, tooltip swap, and callout entrance collapses to an instant transition.

Credits

  • Extracted from: craftingattention (app/src/lessons/primitives/systems/ContextWindowViz.tsx). The source was a lesson component using CA's per-track palette tokens (--color-accent-400, --color-ink-*, --color-success-400, --color-surface-raised) and CA-specific spring aliases (SPRINGS.snappy, SPRINGS.gentle). The craft-bits extract re-keys every theme colour to the semantic --cb-* palette (var(--cb-accent), var(--cb-fg), var(--cb-fg-muted), var(--cb-fg-subtle), var(--cb-success), var(--cb-warning), var(--cb-error), var(--cb-bg-elevated), var(--cb-bg-muted)) so consumer themes repaint freely. The per-section oklch fills survive as default props because they encode section identity rather than theme. Every transition is routed through the canonical SPRINGS.snap / SPRINGS.smooth from @craft-bits/core/motion. The previously hard-coded 6-section anatomy is now the sections prop with the original story as the default. forwardRef + cn() + spread ...props were added to match the library's interactive-component API, and the source's ca-narration utility class was replaced with an inline tokenised wrapper.