<!-- source-hash: 53f316e6709d2c8161bb544234df2d3a -->
Centralises Tailwind/ODS className generation for the chat-adjacent UI chip family, ensuring consistent styling across citation chips, inline entity-card pills, and search-result dropdown rows.

## Key Components

### `ChipClassOptions` (interface)

| Property | Type | Description |
|----------|------|-------------|
| `tone` | `'primary' \| 'secondary'` | Controls resting text color — `primary` matches body text; `secondary` is muted for metadata |
| `density` | `'chip' \| 'list-row' \| 'card-row'` | Controls size/padding variant. Defaults to `'chip'` |
| `extra` | `string` | Optional additional classes appended verbatim (e.g. `cursor-pointer`) |

### `chatChipClass(options)` (function)

Accepts a `ChipClassOptions` object and returns a composed Tailwind class string. All three density variants share the same border, hover transition, and accent treatment so they read as one UI family regardless of size.

| Density | Sizing | Frame |
|---------|--------|-------|
| `chip` | `px-2 py-0.5 text-[11px]` | bordered card bg |
| `list-row` | `px-3 py-2 text-sm` | bordered card bg |
| `card-row` | `px-2 py-1 text-[11px]` | no border/bg |

## Usage Example

```typescript
import { chatChipClass } from './chip-styles'

// Citation chip (default density)
const citationClass = chatChipClass({ tone: 'secondary' })

// Search dropdown row
const dropdownRowClass = chatChipClass({
  tone: 'primary',
  density: 'list-row',
  extra: 'cursor-pointer w-full',
})

// Tracking strip under a card frame
const cardRowClass = chatChipClass({
  tone: 'secondary',
  density: 'card-row',
})
```

> **Design note:** A single ODS token change here propagates to all three surfaces simultaneously — citation chips, inline entity markers, and search results will always render as the same visual family.