# Text

A run of text in the theme's type scale and colours, so a page sets its words without writing classes. Anything not set is inherited from around it. A colour never carries the meaning on its own: a destructive or warning tone goes with words that say what is wrong.

- Registry name: `text` (`@candor/text`)
- 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/text

## Install

```bash
npx candor-ui add text
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/text`.
It brings in: tokens, utils.
npm packages: @base-ui/react@^1.9.0.

## Example

```tsx
"use client"

import { Text } from "@/components/candor/text"

export default function Example() {
  return (
    <div className="flex max-w-md flex-col gap-2">
      <Text size="lg" weight="semibold">
        Nightly sync
      </Text>
      <Text tone="muted" size="sm">
        Copies changed accounts from the CRM to the warehouse every night at 02:00.
      </Text>
      <Text tone="warning" size="sm">
        Last run finished with 3 skipped records.
      </Text>
      <Text tone="faint" size="xs" truncate className="max-w-60">
        Owner: data-platform-oncall@company.example, escalation after two failed runs
      </Text>
    </div>
  )
}
```

## <Text>

Props:

- `tone?: TextTone | undefined`: The colour, by what the text is: `muted` for secondary words, `faint` for the least important. Inherited when left out.
- `size?: TextSize | undefined`: The step of the type scale. Inherited when left out.
- `weight?: keyof typeof weights | undefined`: How heavy the type is. Inherited when left out.
- `truncate?: boolean | undefined` (default `false`): Keeps the text on one line and ends it with an ellipsis where it doesn't fit. The whole text stays in the page, so a screen reader reads all of it; give a way to see the rest (a tooltip, a detail view) where it matters. Only a box can cut its text, so a truncated Text is drawn as a block, a `<span>` too; for one inside a line, give it `className="inline-block max-w-…"`.
- `render?: useRender.RenderProp | undefined`: The element to draw instead of a `<p>`: `render={<span />}` for text inside a line.
- `className?: string | undefined`: Classes for the element, applied last, so they win over the props.
- `children?: React.ReactNode | undefined`: The words.

Also takes the props of `Omit<React.ComponentProps<"p">, "color">`.

## Values

### textTones

A tone's class. The status tones are the theme's `*-text` colours, which it checks for contrast on the page.

```ts
const textTones: Record<TextTone, string>
```

## Types

### TextTone

A text colour by what it says, from the theme's foreground roles: never a raw colour.

```ts
"default" | "muted" | "faint" | "destructive" | "success" | "warning"
```

### TextSize

A step of the type scale. `base` is body text, which follows `data-density`.

```ts
"2xs" | "xs" | "sm" | "base" | "lg" | "xl"
```

## 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`: its fixed strings in `strings`, its nouns in `nouns`; entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
