Retrieved Context Chunks
The RAG debugging surface: ranked passages with similarity as a meter, matched spans in real mark elements, and filter chips wired as a radiogroup so arrows move between them.
What is in the context and what fell out of it — a stacked budget with the reply reserve drawn as a segment, and the dropped chunks named with the reason, which is the part nobody ships.
components/context-window-budget.tsxnpx hoverlab add context-window-budget
Or over MCP, from your editor's agent — no account needed.
Free to read, copy and install, for personal and non-commercial projects. Shipping it in client work or a paid product needs Pro ($79 once). The source lands in your repo and stops being ours — no attribution, nothing to upgrade.
Start a page with this section — add more, order them, and leave with the page source.
27.0k of 32.0k tokens · 84%
The model did not see any of this. If an answer looks like it ignored a document, start here.
Rendered live in your current theme — this is the same component whose source is below, not a screenshot of it.
'use client'
/**
* <ContextWindowBudget> — what is in the context, and what fell out of it.
*
* Retrieval & Context had the source picker, the chunk cards, the citation
* list and the empty state: four views of what the model *used*. None of
* them can answer the question people actually ask when an answer is
* wrong — "did it even see the file?" This is that view.
*
* THE ONE THING THIS GETS RIGHT THAT MOST DO NOT
*
* The dropped items are on screen, with the reason. Every retrieval
* pipeline evicts something: a chunk that ranked eighth when only seven
* fit, a conversation turn that aged out, a 4MB PDF nothing was ever going
* to fit whole. Products show the seven and stay silent about the eighth,
* so the failure looks like the model ignoring a document rather than the
* document never arriving. Naming the eighth turns an unfalsifiable
* complaint into a fixable one — and the fix is usually "pin it", which is
* a control here.
*
* THE RESERVE IS DRAWN AS PART OF THE BAR
*
* A context that is 100% full cannot reply. The room held back for the
* answer is a segment like any other, not headroom left over at the end,
* because it is the segment that gets eaten first when somebody pins four
* more files and then wonders why replies got shorter.
*
* PERCENTAGES AND TOKENS, BOTH
*
* Tokens are the unit that runs out and the one the bill is in; per cent
* is the only unit anybody can read off a bar. Showing one without the
* other means either a number nobody can place or a proportion nobody can
* act on.
*
* ACCESSIBILITY: the bar is a `role="img"` with an `aria-label` carrying
* the whole breakdown in words — a screen-reader user gets the summary in
* one string instead of a dozen unlabelled divs, and the same numbers are
* in the legend below for anyone reading it as a list. Pin buttons are
* `aria-pressed` toggles, so their state is real rather than implied by a
* filled icon.
*/
import * as React from 'react'
import {
AlertTriangle,
CornerDownLeft,
FileText,
MessagesSquare,
Pin,
Settings2,
Wrench,
} from 'lucide-react'
export type SegmentKind = 'system' | 'tools' | 'history' | 'retrieved' | 'reserve'
export interface ContextItem {
id: string
label: string
detail: string
tokens: number
kind: SegmentKind
pinned?: boolean
}
export interface DroppedItem {
label: string
tokens: number
/** Why it did not make it in. Never omitted — it is the whole point. */
reason: string
}
export interface ContextWindowBudgetProps {
windowTokens?: number
reserveTokens?: number
items?: ContextItem[]
dropped?: DroppedItem[]
className?: string
}
const DEFAULT_ITEMS: ContextItem[] = [
{ id: 'sys', label: 'System prompt', detail: 'Agent role and house rules', tokens: 1_400, kind: 'system' },
{ id: 'tools', label: 'Tool definitions', detail: '9 tools, JSON schema', tokens: 3_100, kind: 'tools' },
{ id: 'hist', label: 'Conversation', detail: 'Last 14 turns', tokens: 8_200, kind: 'history' },
{
id: 'doc-1',
label: 'refunds-policy.md',
detail: 'Whole file · pinned by you',
tokens: 4_800,
kind: 'retrieved',
pinned: true,
},
{
id: 'doc-2',
label: 'Q3-support-metrics.csv',
detail: 'Rows 1–200 of 4,812',
tokens: 4_400,
kind: 'retrieved',
},
{
id: 'doc-3',
label: 'escalation-runbook.md',
detail: '3 of 9 sections, ranked by the query',
tokens: 2_900,
kind: 'retrieved',
},
]
const DEFAULT_DROPPED: DroppedItem[] = [
{
label: 'Q3-support-metrics.csv — rows 201–4,812',
tokens: 96_000,
reason: 'Too large for the window. Only the first 200 rows were sent.',
},
{
label: 'contract-meridian-2024.pdf',
tokens: 18_300,
reason: 'Ranked 8th; seven chunks fitted. Pin it to force it in.',
},
{
label: 'Conversation turns 1–6',
tokens: 7_100,
reason: 'Aged out of the rolling history window.',
},
]
const KIND_LABEL: Record<SegmentKind, string> = {
system: 'System',
tools: 'Tools',
history: 'Conversation',
retrieved: 'Retrieved',
reserve: 'Held for the reply',
}
const KIND_ICON: Record<SegmentKind, React.ComponentType<{ className?: string }>> = {
system: Settings2,
tools: Wrench,
history: MessagesSquare,
retrieved: FileText,
reserve: CornerDownLeft,
}
/*
The catalog's series ramp: color-mix in oklab, walking each step toward
the card colour. These tokens are oklch(), so hsl(var(--primary)) is not
a colour at all — the declaration is dropped and the segment renders
invisible against the track.
*/
function rampColor(step: number, steps: number) {
const toward = steps <= 1 ? 0 : (step / (steps - 1)) * 78
return `color-mix(in oklab, var(--primary) ${100 - toward}%, var(--card))`
}
function compact(tokens: number) {
return tokens >= 1000 ? `${(tokens / 1000).toFixed(1)}k` : String(tokens)
}
export function ContextWindowBudget({
windowTokens = 32_000,
reserveTokens = 2_200,
items = DEFAULT_ITEMS,
dropped = DEFAULT_DROPPED,
className = '',
}: ContextWindowBudgetProps) {
const [pinned, setPinned] = React.useState<string[]>(
items.filter((i) => i.pinned).map((i) => i.id),
)
const used = items.reduce((sum, i) => sum + i.tokens, 0)
/* Drawn as a segment, not as leftover space — see the note above. */
const segments = [
...items,
{
id: 'reserve',
label: KIND_LABEL.reserve,
detail: 'Room the answer needs',
tokens: reserveTokens,
kind: 'reserve' as SegmentKind,
},
]
const committed = used + reserveTokens
const free = Math.max(0, windowTokens - committed)
const pct = (t: number) => (t / windowTokens) * 100
const summary = `${compact(committed)} of ${compact(windowTokens)} tokens committed: ${segments
.map((s) => `${s.label} ${Math.round(pct(s.tokens))}%`)
.join(', ')}. ${compact(free)} free.`
return (
<section className={`mx-auto w-full max-w-2xl px-4 py-16 sm:px-6 ${className}`}>
<div className="rounded-2xl border border-border bg-card p-5">
<header className="flex flex-wrap items-baseline gap-x-3 gap-y-1">
<h2 className="text-base font-semibold text-foreground">Context for this reply</h2>
<p className="text-sm text-muted-foreground">
{/* The unit that runs out, and the unit anyone can read. */}
<span className="tabular-nums text-foreground">{compact(committed)}</span> of{' '}
<span className="tabular-nums">{compact(windowTokens)}</span> tokens ·{' '}
<span className="tabular-nums">{Math.round(pct(committed))}%</span>
</p>
</header>
{/* One label carrying the whole breakdown, rather than a dozen divs. */}
<div
role="img"
aria-label={summary}
className="mt-4 flex h-3 w-full gap-0.5 overflow-hidden rounded-full border border-transparent bg-muted"
>
{segments.map((seg, i) => (
<div
key={seg.id}
style={{
width: `${pct(seg.tokens)}%`,
background:
seg.kind === 'reserve'
? 'color-mix(in oklab, var(--muted-foreground) 45%, var(--card))'
: rampColor(i, segments.length - 1),
}}
className="h-full border border-transparent first:rounded-s-full"
/>
))}
</div>
<ul className="mt-4 space-y-2">
{segments.map((seg, i) => {
const Icon = KIND_ICON[seg.kind]
const isPinned = pinned.includes(seg.id)
const canPin = seg.kind === 'retrieved'
return (
<li key={seg.id} className="flex items-center gap-3">
<span
aria-hidden
style={{
background:
seg.kind === 'reserve'
? 'color-mix(in oklab, var(--muted-foreground) 45%, var(--card))'
: rampColor(i, segments.length - 1),
}}
className="h-2.5 w-2.5 shrink-0 rounded-sm border border-transparent"
/>
<Icon aria-hidden className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
<span className="min-w-0 flex-1">
<span className="block truncate text-sm text-foreground">{seg.label}</span>
<span className="block truncate text-xs text-muted-foreground">
{seg.detail}
</span>
</span>
<span className="shrink-0 text-end text-xs tabular-nums text-muted-foreground">
{compact(seg.tokens)}
<span className="ms-1.5 text-foreground">{Math.round(pct(seg.tokens))}%</span>
</span>
{canPin ? (
<button
type="button"
aria-pressed={isPinned}
onClick={() =>
setPinned((p) =>
p.includes(seg.id) ? p.filter((x) => x !== seg.id) : [...p, seg.id],
)
}
className={`inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-lg transition hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background ${
isPinned ? 'text-primary' : 'text-muted-foreground'
}`}
>
<Pin aria-hidden className="h-3.5 w-3.5" />
<span className="sr-only">
{isPinned ? 'Unpin' : 'Pin'} {seg.label}
</span>
</button>
) : (
<span className="h-7 w-7 shrink-0" />
)}
</li>
)
})}
</ul>
{/* The part nobody ships. */}
{dropped.length > 0 ? (
<div className="mt-5 rounded-xl border border-border bg-muted/40 p-4">
<h3 className="flex items-center gap-2 text-sm font-semibold text-foreground">
<AlertTriangle aria-hidden className="h-4 w-4 text-amber-600 dark:text-amber-400" />
Left out to make it fit
</h3>
<p className="mt-1 text-xs text-muted-foreground">
The model did not see any of this. If an answer looks like it
ignored a document, start here.
</p>
<ul className="mt-3 space-y-2">
{dropped.map((d) => (
<li key={d.label} className="flex gap-3 text-xs">
<span className="min-w-0 flex-1">
<span className="block truncate font-medium text-foreground">
{d.label}
</span>
<span className="block text-muted-foreground">{d.reason}</span>
</span>
<span className="shrink-0 tabular-nums text-muted-foreground">
{compact(d.tokens)}
</span>
</li>
))}
</ul>
</div>
) : null}
</div>
</section>
)
}
bg-card, text-muted-foreground) — it inherits your theme instead of overriding it.Drop it at components/context-window-budget.tsx and import it where you need the section:
import { ContextWindowBudget } from '@/components/context-window-budget'Read out of the component’s own type and signature, so this cannot drift from the source below. Every prop has a default — the component renders standalone before you pass it anything.
| Prop | Type | Default |
|---|---|---|
windowTokens | number | 32_000 |
reserveTokens | number | 2_200 |
items | ContextItem[] | DEFAULT_ITEMS |
dropped | DroppedItem[] | DEFAULT_DROPPED |
className | string | '' |
The same block rendered once to markup, wrapped as a file your framework compiles. Tailwind classes are framework-agnostic, so the design transfers intact — the behaviour does not.
This block is interactive. The markup below is its initial state with the event handlers stripped — you will need to re-wire the behaviour in your framework.
<!--
Context Window Budget — markup from the Hoverlab catalog.
This is the block rendered once to HTML and wrapped as a component
file. It is not a port of the React source: the Tailwind classes carry
the design, which is the part that took the work, and they are the same
in every framework.
This block is interactive in React and the handlers are NOT here.
Buttons, toggles and menus render in their initial state and do
nothing until you wire them up.
-->
<section class="mx-auto w-full max-w-2xl px-4 py-16 sm:px-6 ">
<div class="rounded-2xl border border-border bg-card p-5">
<header class="flex flex-wrap items-baseline gap-x-3 gap-y-1">
<h2 class="text-base font-semibold text-foreground">Context for this reply</h2>
<p class="text-sm text-muted-foreground"><span class="tabular-nums text-foreground">27.0k</span> of <span class="tabular-nums">32.0k</span> tokens · <span class="tabular-nums">84%</span></p>
</header>
<div role="img" aria-label="27.0k of 32.0k tokens committed: System prompt 4%, Tool definitions 10%, Conversation 26%, refunds-policy.md 15%, Q3-support-metrics.csv 14%, escalation-runbook.md 9%, Held for the reply 7%. 5.0k free." class="mt-4 flex h-3 w-full gap-0.5 overflow-hidden rounded-full border border-transparent bg-muted">
<div style="width:4.375%;background:color-mix(in oklab, var(--primary) 100%, var(--card))" class="h-full border border-transparent first:rounded-s-full"></div>
<div style="width:9.6875%;background:color-mix(in oklab, var(--primary) 84.4%, var(--card))" class="h-full border border-transparent first:rounded-s-full"></div>
<div style="width:25.624999999999996%;background:color-mix(in oklab, var(--primary) 68.8%, var(--card))" class="h-full border border-transparent first:rounded-s-full"></div>
<div style="width:15%;background:color-mix(in oklab, var(--primary) 53.2%, var(--card))" class="h-full border border-transparent first:rounded-s-full"></div>
<div style="width:13.750000000000002%;background:color-mix(in oklab, var(--primary) 37.599999999999994%, var(--card))" class="h-full border border-transparent first:rounded-s-full"></div>
<div style="width:9.0625%;background:color-mix(in oklab, var(--primary) 22%, var(--card))" class="h-full border border-transparent first:rounded-s-full"></div>
<div style="width:6.875000000000001%;background:color-mix(in oklab, var(--muted-foreground) 45%, var(--card))" class="h-full border border-transparent first:rounded-s-full"></div>
</div>
<ul class="mt-4 space-y-2">
<li class="flex items-center gap-3">
<span aria-hidden="true" style="background:color-mix(in oklab, var(--primary) 100%, var(--card))" class="h-2.5 w-2.5 shrink-0 rounded-sm border border-transparent"></span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings2 lucide-settings-2 h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true">
<path d="M14 17H5"></path>
<path d="M19 7h-9"></path>
<circle cx="17" cy="17" r="3"></circle>
<circle cx="7" cy="7" r="3"></circle>
</svg>
<span class="min-w-0 flex-1">
<span class="block truncate text-sm text-foreground">System prompt</span>
<span class="block truncate text-xs text-muted-foreground">Agent role and house rules</span>
</span>
<span class="shrink-0 text-end text-xs tabular-nums text-muted-foreground">1.4k<span class="ms-1.5 text-foreground">4%</span></span>
<span class="h-7 w-7 shrink-0"></span>
</li>
<li class="flex items-center gap-3">
<span aria-hidden="true" style="background:color-mix(in oklab, var(--primary) 84.4%, var(--card))" class="h-2.5 w-2.5 shrink-0 rounded-sm border border-transparent"></span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-wrench h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true">
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path>
</svg>
<span class="min-w-0 flex-1">
<span class="block truncate text-sm text-foreground">Tool definitions</span>
<span class="block truncate text-xs text-muted-foreground">9 tools, JSON schema</span>
</span>
<span class="shrink-0 text-end text-xs tabular-nums text-muted-foreground">3.1k<span class="ms-1.5 text-foreground">10%</span></span>
<span class="h-7 w-7 shrink-0"></span>
</li>
<li class="flex items-center gap-3">
<span aria-hidden="true" style="background:color-mix(in oklab, var(--primary) 68.8%, var(--card))" class="h-2.5 w-2.5 shrink-0 rounded-sm border border-transparent"></span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-messages-square h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true">
<path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2z"></path>
<path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1"></path>
</svg>
<span class="min-w-0 flex-1">
<span class="block truncate text-sm text-foreground">Conversation</span>
<span class="block truncate text-xs text-muted-foreground">Last 14 turns</span>
</span>
<span class="shrink-0 text-end text-xs tabular-nums text-muted-foreground">8.2k<span class="ms-1.5 text-foreground">26%</span></span>
<span class="h-7 w-7 shrink-0"></span>
</li>
<li class="flex items-center gap-3">
<span aria-hidden="true" style="background:color-mix(in oklab, var(--primary) 53.2%, var(--card))" class="h-2.5 w-2.5 shrink-0 rounded-sm border border-transparent"></span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true">
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"></path>
<path d="M14 2v4a2 2 0 0 0 2 2h4"></path>
<path d="M10 9H8"></path>
<path d="M16 13H8"></path>
<path d="M16 17H8"></path>
</svg>
<span class="min-w-0 flex-1">
<span class="block truncate text-sm text-foreground">refunds-policy.md</span>
<span class="block truncate text-xs text-muted-foreground">Whole file · pinned by you</span>
</span>
<span class="shrink-0 text-end text-xs tabular-nums text-muted-foreground">4.8k<span class="ms-1.5 text-foreground">15%</span></span>
<button type="button" aria-pressed="true" class="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-lg transition hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background text-primary">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pin h-3.5 w-3.5" aria-hidden="true">
<path d="M12 17v5"></path>
<path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"></path>
</svg>
<span class="sr-only">Unpin refunds-policy.md</span>
</button>
</li>
<li class="flex items-center gap-3">
<span aria-hidden="true" style="background:color-mix(in oklab, var(--primary) 37.599999999999994%, var(--card))" class="h-2.5 w-2.5 shrink-0 rounded-sm border border-transparent"></span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true">
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"></path>
<path d="M14 2v4a2 2 0 0 0 2 2h4"></path>
<path d="M10 9H8"></path>
<path d="M16 13H8"></path>
<path d="M16 17H8"></path>
</svg>
<span class="min-w-0 flex-1">
<span class="block truncate text-sm text-foreground">Q3-support-metrics.csv</span>
<span class="block truncate text-xs text-muted-foreground">Rows 1–200 of 4,812</span>
</span>
<span class="shrink-0 text-end text-xs tabular-nums text-muted-foreground">4.4k<span class="ms-1.5 text-foreground">14%</span></span>
<button type="button" aria-pressed="false" class="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-lg transition hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background text-muted-foreground">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pin h-3.5 w-3.5" aria-hidden="true">
<path d="M12 17v5"></path>
<path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"></path>
</svg>
<span class="sr-only">Pin Q3-support-metrics.csv</span>
</button>
</li>
<li class="flex items-center gap-3">
<span aria-hidden="true" style="background:color-mix(in oklab, var(--primary) 22%, var(--card))" class="h-2.5 w-2.5 shrink-0 rounded-sm border border-transparent"></span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true">
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"></path>
<path d="M14 2v4a2 2 0 0 0 2 2h4"></path>
<path d="M10 9H8"></path>
<path d="M16 13H8"></path>
<path d="M16 17H8"></path>
</svg>
<span class="min-w-0 flex-1">
<span class="block truncate text-sm text-foreground">escalation-runbook.md</span>
<span class="block truncate text-xs text-muted-foreground">3 of 9 sections, ranked by the query</span>
</span>
<span class="shrink-0 text-end text-xs tabular-nums text-muted-foreground">2.9k<span class="ms-1.5 text-foreground">9%</span></span>
<button type="button" aria-pressed="false" class="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-lg transition hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background text-muted-foreground">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pin h-3.5 w-3.5" aria-hidden="true">
<path d="M12 17v5"></path>
<path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"></path>
</svg>
<span class="sr-only">Pin escalation-runbook.md</span>
</button>
</li>
<li class="flex items-center gap-3">
<span aria-hidden="true" style="background:color-mix(in oklab, var(--muted-foreground) 45%, var(--card))" class="h-2.5 w-2.5 shrink-0 rounded-sm border border-transparent"></span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-corner-down-left h-3.5 w-3.5 shrink-0 text-muted-foreground" aria-hidden="true">
<path d="M20 4v7a4 4 0 0 1-4 4H4"></path>
<path d="m9 10-5 5 5 5"></path>
</svg>
<span class="min-w-0 flex-1">
<span class="block truncate text-sm text-foreground">Held for the reply</span>
<span class="block truncate text-xs text-muted-foreground">Room the answer needs</span>
</span>
<span class="shrink-0 text-end text-xs tabular-nums text-muted-foreground">2.2k<span class="ms-1.5 text-foreground">7%</span></span>
<span class="h-7 w-7 shrink-0"></span>
</li>
</ul>
<div class="mt-5 rounded-xl border border-border bg-muted/40 p-4">
<h3 class="flex items-center gap-2 text-sm font-semibold text-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle-alert h-4 w-4 text-amber-600 dark:text-amber-400" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"></path><path d="M12 9v4"></path><path d="M12 17h.01"></path></svg>Left out to make it fit</h3>
<p class="mt-1 text-xs text-muted-foreground">The model did not see any of this. If an answer looks like it ignored a document, start here.</p>
<ul class="mt-3 space-y-2">
<li class="flex gap-3 text-xs">
<span class="min-w-0 flex-1">
<span class="block truncate font-medium text-foreground">Q3-support-metrics.csv — rows 201–4,812</span>
<span class="block text-muted-foreground">Too large for the window. Only the first 200 rows were sent.</span>
</span>
<span class="shrink-0 tabular-nums text-muted-foreground">96.0k</span>
</li>
<li class="flex gap-3 text-xs">
<span class="min-w-0 flex-1">
<span class="block truncate font-medium text-foreground">contract-meridian-2024.pdf</span>
<span class="block text-muted-foreground">Ranked 8th; seven chunks fitted. Pin it to force it in.</span>
</span>
<span class="shrink-0 tabular-nums text-muted-foreground">18.3k</span>
</li>
<li class="flex gap-3 text-xs">
<span class="min-w-0 flex-1">
<span class="block truncate font-medium text-foreground">Conversation turns 1–6</span>
<span class="block text-muted-foreground">Aged out of the rolling history window.</span>
</span>
<span class="shrink-0 tabular-nums text-muted-foreground">7.1k</span>
</li>
</ul>
</div>
</div>
</section>
What each framework gets across the whole catalog — effects convert properly; this rung is markup.
The component, its props, the design tokens it expects and the command that installs it — as one prompt. Paste it into Claude, Cursor, v0 or ChatGPT and what they build around it will match the rest of the catalog instead of inventing its own system.
Want the whole screen instead of this one section? Open a page and copy it entire.
All of them free to read, copy and install — no account, no locked tiles, no watermarked preview. The whole catalog is open, and so are the API and the CLI.
Browse Retrieval & ContextCopying the code is free. Putting it in client work or a paid product is what Pro is for — the licence, not the access.
The RAG debugging surface: ranked passages with similarity as a meter, matched spans in real mark elements, and filter chips wired as a radiogroup so arrows move between them.
The published footnotes under an answer — ordered list, real cite and time elements, the claim each source supports, and a staleness warning written in words rather than shown as an amber dot.
Choosing what the assistant may read, with indexing state told honestly — a half-indexed source says so rather than showing a green tick — and the footer stating the effect of the selection, not its cardinality.
The refusal screen: says plainly that nothing was found, shows where it looked and the near-misses below threshold, and offers the two real ways out instead of inventing an answer.
A green tick means the connector works, not that the answers are current. Freshness as an age in words per source, the headline taken from the stalest one, and a failed sync that still says what age it is answering from.
Retrieved sources ranked by how stale they are, because a confident answer from a two-year-old document is the failure people do not catch.
Which sources this answer may draw on, shown as a scope the user can read before asking rather than a citation list after.
How an answer is tied to its sources, and what the system does when it cannot find any.