<!-- Generated by emit-docs.ts — do not edit. -->
# Tooltip

Short hover/focus hint attached to a single trigger element.

## Props

| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
| `content` | `ReactNode` | — | yes | Tooltip content. |
| `children` | `ReactElement<Record<string, unknown>, string \| JSXElementConstructor<any>>` | — | yes | The trigger element (must accept ref, onMouseEnter/Leave, onFocus/Blur). |
| `placement` | `"top" \| "bottom" \| "left" \| "right"` | top | no | Preferred placement. |

## Keyboard & assistive tech

| Keys | Behavior |
|---|---|
| Tab (focus trigger) | Shows immediately on focus (no delay). |
| Escape | Dismisses while visible (WCAG 1.4.13). |

Hover opens after a short delay; content is linked via aria-describedby while visible. Trigger must accept onMouseEnter/Leave and onFocus/Blur props (cloned in automatically) — no ref forwarding required.

## Theming

Override `--psi-tooltip-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).



## Rules

- One accent per visual group; everything else neutral or ghost.
- danger only for actions with real consequences.
- Sizes are px numbers (24|32|40|48), never S/M/L.
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
