# Chat foundations
> What @sdxc/ui/chat is for, the structure and scrolling rules its parts share, and every variable it reads.

A conversation: a scrolling log, one row per turn with avatar, header and footer, bubbles, inline markers and attachment cards.

Everything is server HTML; following the latest message and opening an attachment are mixins you add where the thread updates live.

Import the components from `@sdxc/ui/chat` and the theme once from `@sdxc/ui/theme.css`.

## When to reach for it

- A support inbox, a team thread or any log of messages between people.
- An assistant's conversation, with streamed replies and Markdown inside the bubbles.
- Any feed where new entries arrive at the bottom and a reader may scroll back.

## Shared ideas

- **Structure.** `Message` is an `article` on a grid filled by `data-slot`; the namespace renders no headings.
- **Container layout.** `Message`, `MessageScroller` and `Attachment` reflow on their own width, wherever the thread sits.
- **Direction.** Bubble corners and margins are logical properties, so end-aligned bubbles mirror in RTL.
- **Scrolling.** `messageFollow` keeps the log at the latest turn until the reader scrolls away; instant under reduced motion.
- **Accessibility.** The log is `role="log"` with `aria-busy` for streaming; reactions are a labelled group.
- **Markdown.** Wrap a reply in `<Typeset preset="chat">`: 15px on a 1.5 line.

## CSS variables

Every custom property the namespace reads or declares. Reads the neutral and brand roles, danger for a failed bubble, and all five roles through Marker's color. The roles are documented on Theming.

### Spacing and measure

None is declared in `theme.css`; set any of them on an ancestor of the thread.

| Variable | Default | What it controls |
| --- | --- | --- |
| `--ui-message-gap` | `0.75rem` | Gap between a message's avatar and its header and content. |
| `--ui-message-row-gap` | `0.25rem` | Gap between a message's header, content and footer. |
| `--ui-message-content-max-size` | `36rem` | Widest a turn's content grows, its reading measure. |
| `--ui-message-group-gap` | `0.125rem` | Gap between consecutive messages in a Message.Group. |
| `--ui-marker-gap` | `0.375rem` | Gap between a `Marker`'s icon, label and rules. |
| `--ui-message-scroller-anchor-offset` | `0px` | Space a scrolled-to turn leaves above itself, to clear an overlay. |
| `--ui-separator-thickness` | `1px` | Thickness of a separator `Marker`'s rules. |

### Shape and elevation

Read through `@sdxc/u`'s `rounded()` and `shadow()`; each default is the fallback an app overrides by declaring the variable.

| Variable | Default | What it controls |
| --- | --- | --- |
| `--ui-radius-xs` | `0.125rem` | The tight corner where a bubble meets its sender's edge or a grouped neighbour. |
| `--ui-radius-md` | `0.375rem` | Corners of a `Marker` and an attachment's media. |
| `--ui-radius-lg` | `0.5rem` | Corners of the scroller's frame and an attachment card. |
| `--ui-radius-xl` | `0.75rem` | Corners of a bubble. |
| `--ui-shadow-md` | `0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)` | Elevation of the jump-to-latest button. |
| `--ui-bg` | `var(--ui-neutral-bg-tint, Canvas)` | Opaque fill of the jump-to-latest button. |

### Set by the components

| Variable | Default | What it controls |
| --- | --- | --- |
| `--ui-bubble-reactions-justify` | `set by Bubble from align` | Which side a bubble's reactions row lines up with. |
