# Result card

A finished piece of work, handed over: the answer first, in a few lines, then the receipt (what it cost, how long it took, what checked it) and the files to open or download, then your actions (Accept, Ask for changes). The receipt prints your values as given; a line you don't know is a line you leave out, never an estimate dressed as a fact. The answer is read into safe blocks, never HTML.

- Registry name: `result-card` (`@candor/result-card`)
- Tier: Pro. Installing it needs a Pro, Premium or Team licence key: the person runs `npx candor-ui key <key>` themselves; never ask for the key in chat or write it to a file.
- Docs: https://candor.themethodic.com/docs/result-card

## Install

```bash
npx candor-ui add result-card
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/result-card`.
It brings in: chat, file-list, locale, message-content, safe-markdown, work, utils.

## Example

```tsx
"use client"

import { ResultCard } from "@/components/result-card"
import { Button } from "@/components/ui/button"

export default function Example() {
  return (
    <ResultCard
      className="max-w-xl"
      title="Pricing review"
      status={{ label: "Checked", tone: "success" }}
      // The answer first, as markdown text: read into safe blocks, never HTML.
      answer={"Merge **Starter** and **Basic** into one plan at the Starter price. The three plans left cover 92% of last quarter's revenue.\n\nAnnual discounts and grandfathered contracts don't change."}
      // Your values as given; leave out what you don't know.
      receipt={[
        { label: "Cost", value: "$1.84", note: "of a $4 limit" },
        { label: "Took", value: "11 minutes" },
        { label: "Checked by", value: "Checker, against the source sheet" },
      ]}
      files={[{ id: "report", name: "Pricing review.docx", size: 48_000, readable: true, formats: [{ id: "docx", label: "Word" }, { id: "pdf", label: "PDF" }] }]}
      onOpenFile={() => {}}
      onDownloadFile={() => {}}
      actions={
        <>
          <Button variant="ghost" size="sm">
            Ask for changes
          </Button>
          <Button size="sm">Accept</Button>
        </>
      }
    />
  )
}
```

## <ResultCard>

Props:

- `title: string`: What it is, as the heading: "Result 1", "Pricing review".
- `answer: string | MessageBlock[]`: The answer, first: markdown text (read into safe blocks) or blocks.
- `status?: { label: string; tone?: "default" | "attention" | "success" | undefined } | undefined`: Where it stands, in words, with a tone: `{ label: "Checked", tone: "success" }`.
- `receipt?: ReceiptLine[] | undefined`: What it cost, how long it took, what checked it: your values, as given.
- `files?: Deliverable[] | undefined`: The files it produced.
- `onOpenFile?: ((id: string) => void) | undefined`: Adds Open to readable files.
- `onDownloadFile?: ((id: string, format?: string) => void) | undefined`: Adds Download to files; called with the file's id and format.
- `actions?: React.ReactNode | undefined`: Buttons at the foot: Accept, Ask for changes.
- `sources?: MessageSource[] | undefined`: Sources the answer cites by marker.
- `onOpenEntity?: ((entity: EntityRef) => void) | undefined`: Makes entity chips in the answer open their thing.
- `className?: string | undefined`

## Strings (`resultCard`)

The fixed words, English by default. Override any of them under `resultCard` in `<LocaleProvider strings={{ resultCard: { … } }}>`; the table is exported as `resultCardStrings`.

- `receipt`: Receipt
- `files`: Files

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider` (fixed strings) and `TermsProvider` (nouns); entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
