# Heading

A heading whose level is the page's outline and whose size is only how it looks, so a small heading deep in a card can still be an `<h2>`. `level` is required: a screen reader's list of headings is the page's table of contents, and a level guessed from a size gets it wrong. It reads no `HeadingScope` (5.0.0): the level you give is the one drawn, so a heading you place by hand never moves.

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

## Install

```bash
npx candor-ui add heading
```

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

## Example

```tsx
"use client"

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

// The level is the page's outline; the size is only how it looks.
export default function Example() {
  return (
    <div className="flex max-w-md flex-col gap-3">
      <Heading level={2} size="xl">
        Agent settings
      </Heading>
      <Heading level={3} size="sm" tone="muted">
        Permissions
      </Heading>
      <Text size="sm">The agent can read the CRM and draft emails. Sending needs your approval.</Text>
    </div>
  )
}
```

## <Heading>

Props:

- `level: HeadingLevel`: The heading's level in the outline, which picks the element (`2` draws an `<h2>`). Required.
- `size?: HeadingSize | undefined`: How large it looks. Left out, the level sets it: `3xl` for a level 1 down to `sm` for a level 6.
- `tone?: TextTone | undefined`: The colour, by what the heading is. Inherited when left out.
- `render?: useRender.RenderProp | undefined`: The element to draw instead of the level's `<h1>` to `<h6>`. One that isn't the level's heading element is given `role="heading"` and `aria-level`, so the outline stays true; a function that returns the level's element isn't.
- `className?: string | undefined`: Classes for the element, applied last, so they win over the props.
- `children?: React.ReactNode | undefined`: The heading's words.

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

## Values

### headingSizes

The size each level draws at when `size` is left out.

```ts
const headingSizes: Record<HeadingLevel, HeadingSize>
```

## Types

### HeadingSize

How large a heading looks, a step of the type scale, separate from where it sits in the outline.

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

## Types from other items

The props above take these. Each is defined by another item; import it from the path shown.

### HeadingLevel

Import: `import type { HeadingLevel } from "@/lib/candor/heading-level"` (item `heading-level`, https://candor.themethodic.com/docs/heading-level.md)

A heading's level in the page's outline: `1` is `<h1>`, `6` is `<h6>`. Every Candor item that draws a heading takes its `headingLevel` as this type; the level is where the heading sits in the outline, never how large it looks.

```ts
1 | 2 | 3 | 4 | 5 | 6
```

## 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`.
