Verdict badge
StableKeep, fix, merge or cut: a mono badge where each verdict has its own shape, and the word is always there.
Made for the agent-analytics home pages, where every skill and agent ends with a verdict. Keep is solid, fix is outlined, merge is dashed and cut is struck through on a faint ring. The shapes help a scanning eye; the word does the work.
Updated View source
The four verdicts
import { Fragment } from 'react'import { VerdictBadge } from '@rchursin/home/ui'
const verdicts = [ ['keep', 'Used, and it finishes the job.', 'solid'], ['fix', 'Used, but fails too often.', 'outlined'], ['merge', 'Does the same job as another skill.', 'dashed'], ['cut', 'Nobody has run it in weeks.', 'struck through'],] as const
/** Four verdicts, four shapes. The word is always there too, so nothing rests on the shape alone. */export default function VerdictBadges() { return ( <dl className="grid grid-cols-[auto_1fr] items-center gap-x-5 gap-y-3.5 text-[13px]"> {verdicts.map(([verdict, meaning, shape]) => ( <Fragment key={verdict}> <dt> <VerdictBadge verdict={verdict} /> </dt> <dd className="text-fg-2"> {meaning} <span className="text-fg-3">({shape})</span> </dd> </Fragment> ))} </dl> )}Usage
import { VerdictBadge } from '@rchursin/home/ui'<VerdictBadge verdict="keep" />Examples
In a ledger
The last column of a table, labelled as sample data.
import { useId } from 'react'import { SampleTag, VerdictBadge } from '@rchursin/home/ui'
const rows = [ { name: 'pr-review', runs: 212, success: '91%', verdict: 'keep' }, { name: 'test-fixer', runs: 34, success: '41%', verdict: 'fix' }, { name: 'api-docs', runs: 18, success: '83%', verdict: 'merge' }, { name: 'db-migration-helper', runs: 0, success: '—', verdict: 'cut' },] as const
/** In a table the verdict gets its own column, last, where the eye ends the row. */export default function VerdictLedger() { const captionId = useId() return ( <div className="w-full max-w-md"> <div className="mb-3 flex items-center justify-between gap-3"> <p id={captionId} className="text-[13px] font-semibold"> Skills, last 30 days </p> <SampleTag />API
VerdictBadge props
| Prop | Type | Default | Description |
|---|---|---|---|
verdictrequired | Verdict ('keep' | 'cut' | 'merge' | 'fix') | – | Which verdict. It is also the text shown (in capitals by CSS). |
className | string | – | Extra classes on the badge. |
style | CSSProperties | – | Inline styles, e.g. a delay for the lux-stamp arrival on The Frame. |
Accessibility
- It is a plain span whose text is the verdict, so screen readers read the word; the shape adds nothing they miss.
- The word is lowercase in the markup and capitalised with CSS.
- Cut is struck through and drawn in the secondary grey (stone #737373 on light, fog #a3a3a3 on dark), which meets 4.5:1 on the page and card backgrounds in both themes.
Guidelines
Do
- Put the verdict last in a row, after the numbers that justify it.
- Explain the four verdicts once on the page, as the first example does.
Don’t
- Don’t invent a fifth verdict by colour or opacity.
- Don’t show verdicts for invented data without a sample label.
In use
Related
- Sample badgeA small “Sample data” marker for anything that shows invented records or numbers.
- ChipA small label on a thing, in four shapes (outline, solid, muted, dashed), with an optional icon and remove button.
- Dashboard mockA still picture of the product: four headline numbers, a bar list of skill runs and a ledger with verdicts, on sample data.
- ReceiptA paper receipt for one agent task: torn edges, dotted leaders, a total, and a FIX stamp that lands.
Source
The component’s own files, exactly as they run on this site.
/** * Small building blocks shared by the four home pages. * All black-and-white; every state is told apart by shape or text, never by colour alone. */import { useEffect, useRef, useState, type ComponentPropsWithoutRef, type CSSProperties, type MouseEvent, type ReactNode,} from "react"import { cx } from "../components/cx"import { useIsApple } from "../product/lib/hotkeys"import { copyText } from "../product/ui/code"import type { Verdict } from "./content"
/** Stagger index for .lux-reveal children (each step is 70ms) */export const delay = (d: number) => ({ "--d": d }) as CSSProperties