---
title: Components
description: Every documentation primitive available to authors — callouts, tabs, code, diagrams, cards, steps, badges and API reference blocks — with the Markdown that produces it.
---

Everything on this page is plain Markdown plus the extensions configured in
`mkdocs.yml`. No component needs HTML beyond a wrapping `<div markdown>`, and
none needs page-specific CSS or JavaScript.

## Callouts

Use a callout for information the reader must not miss. One per screen is
plenty; a page full of callouts has none.

!!! note
    A neutral aside. The title defaults to the type name.

!!! info "Before you start"
    Prerequisites and context.

!!! tip
    Advice the reader can act on.

!!! success "Upgrade notes"
    Confirmation that something is safe or complete.

!!! warning
    Something that can go wrong if ignored.

!!! danger "Irreversible"
    Data loss, security exposure or production impact.

!!! example
    A worked example set apart from the main text.

```markdown
!!! warning "Optional title"
    Body, indented four spaces. Any Markdown works here.
```

Types: `note`, `info`, `tip`, `success`, `warning`, `danger`, `example`,
`quote` — plus the aliases `abstract`, `question`, `hint`, `check`, `caution`,
`error`, `failure` and `bug`. Use `!!! note ""` for a callout without a title.

## Expandable sections

Collapsed by default with `???`, open by default with `???+`:

??? question "Why is this collapsed?"
    Long troubleshooting detail or optional depth belongs here, so the page
    stays scannable.

???+ note "Open by default"
    Useful when most readers need it, but some will want to fold it away.

```markdown
??? question "Why is this collapsed?"
    Hidden until the reader opens it.
```

## Tabs

Tabs with the same label stay in sync across the page, and the reader's choice
is remembered on other pages — pick **Python** here and every Python tab opens.

=== "Python"

    Install the client with `pip install httpx`.

=== "TypeScript"

    The standard `fetch` API is all you need.

```markdown
=== "Python"

    Content for Python.

=== "TypeScript"

    Content for TypeScript.
```

## Code

### Code blocks

Fences take a language, an optional title, line numbers and highlighted lines.
Every block gets a copy button.

```python title="client.py" linenums="1" hl_lines="6 7"
import httpx


def wallet(api_url: str, token: str) -> dict:
    """Return the account wallet."""
    response = httpx.get(
        f"{api_url}/developer/account/wallet",
        headers={"authorization": f"Bearer {token}"},
    )
    response.raise_for_status()
    return response.json()
```

````markdown
```python title="client.py" linenums="1" hl_lines="6 7"
…
```
````

### Code groups

A tab set whose tabs each hold one code block becomes a code group:

=== "Python"

    ```python
    wallet = httpx.get(f"{api}/developer/account/wallet", headers=auth).json()
    ```

=== "TypeScript"

    ```typescript
    const wallet = await (await fetch(`${api}/developer/account/wallet`, { headers })).json();
    ```

=== "curl"

    ```console
    $ curl -sS "$YSRA_API_URL/developer/account/wallet" -H "authorization: Bearer $YSRA_TOKEN"
    ```

### Terminal sessions

Use the `console` language for commands with output. Prompts and output are
styled apart, and **copy takes only the commands** — never the `$` or the
output.

```console
$ uv run mkdocs build --strict
INFO    -  Building documentation to directory: site
INFO    -  Documentation built in 1.42 seconds
$ uv run python scripts/check_site.py
✓ 20 pages; initial CSS 10.9 kB + JS 6.5 kB gzipped
```

For a single command with no output, `bash` is fine:

```bash
export YSRA_API_URL="https://api-sandbox.ysra.ai"
```

### Diffs, config and data

```diff
- delivery_mode: preserve_only
+ delivery_mode: draft_pr
```

```yaml title="mkdocs.yml"
nav:
  - Home: index.md
  - Getting started:
      - Quickstart: getting-started/quickstart.md
```

### Inline code

Refer to `fields`, `commands` and `/paths` in backticks. Inline highlighting
takes a language shebang: `#!python Decimal(wallet["available_usd"])`.

## Diagrams

Mermaid fences render as diagrams in the site's own colours and follow the
light and dark themes. Mermaid loads only on pages that have a diagram.

```mermaid
sequenceDiagram
    autonumber
    participant C as Client
    participant A as Ysra API
    participant W as Worker
    C->>A: POST /developer/sessions
    A-->>C: 201 session
    A->>W: dispatch
    W-->>A: checkpoint, evidence
    A-->>C: stream events (WebSocket)
```

````markdown
```mermaid
sequenceDiagram
    Client->>API: POST /developer/sessions
```
````

## Cards

A list inside `<div class="cards" markdown>`. The first link in each item makes
the whole card clickable.

<div class="cards" markdown>

- [**Sessions**](../developer/index.md)

    Lifecycle, checkpoints and steering.

- [**Verification**](../developer/review.md)

    What "verified" means, precisely.

- **Coming soon**

    A card without a link is not clickable.

</div>

```markdown
<div class="cards" markdown>

- [**Sessions**](../developer/index.md)

    Lifecycle, checkpoints and steering.

</div>
```

## Steps

Level-three headings inside `<div class="steps" markdown>` are numbered and
joined by a rail. They still appear in "On this page" and get anchors.

<div class="steps" markdown>

### Install the dependencies

Run `uv sync`.

### Start the preview server

Run `uv run mkdocs serve` and open the printed URL.

### Edit a page

Changes reload in the browser as you save.

</div>

```markdown
<div class="steps" markdown>

### Install the dependencies

Run `uv sync`.

</div>
```

## Badges

**Beta**{ .badge } **Stable**{ .badge .ok } **Deprecated**{ .badge .warn }
**Breaking**{ .badge .danger } **New**{ .badge .accent } **v1.4**{ .badge .info }

```markdown
**Stable**{ .badge .ok }
```

Tones: none, `ok`, `warn`, `danger`, `info`, `accent`. In the sidebar, the
`status: new | beta | deprecated` front matter key adds a badge to a page's
link.

## API reference

An endpoint line, then a definition list of parameters inside
`<div class="params" markdown>`:

`PATCH`{ .patch } `/developer/account/knowledge/{entry_id}`
{ .endpoint }

<div class="params" markdown>

`title` `string`{ .type } *optional*{ .optional }
:   A new title for the entry.

`expected_version` `integer`{ .type } **required**{ .required }
:   The `version` you last read. A stale version returns `409`.

</div>

```markdown
`PATCH`{ .patch } `/developer/account/knowledge/{entry_id}`
{ .endpoint }

<div class="params" markdown>

`expected_version` `integer`{ .type } **required**{ .required }
:   The `version` you last read.

</div>
```

Methods: `.get`, `.post`, `.put`, `.patch`, `.delete`.

## Tables

| Field | Type | Default | Notes |
|---|---|---:|---|
| `limit` | integer | `100` | 1–500 |
| `before` | uuid | — | Cursor: an entry `id` |
| `budget_usd` | decimal string | — | Never a float |

Wide tables scroll inside their frame instead of squeezing columns. Align a
column with `:--`, `:-:` or `--:` in the separator row.

## Text

- **Keyboard keys:** ++cmd+k++ or ++ctrl+k++ opens search; ++slash++ works too.
- **Highlight** with `==text==`: ==decimal strings, never floats==.
- **Insertions and deletions:** ^^added^^ and ~~removed~~.
- **Abbreviations** are defined once and explained on hover: the API returns JSON.
- **Footnotes** collect at the end of the page.[^evidence]
- **Task lists:**
    - [x] Build with `--strict`
    - [ ] Publish a second version with mike

*[JSON]: JavaScript Object Notation
[^evidence]: Like this one.

## Images

Standard Markdown images are lazy-loaded and framed. Add a caption with a
`/// caption` block:

![The Ysra mark: two rings with an orange lens where they overlap](../assets/brand/ysra-mark-512.png){ width="160" height="160" }
/// caption
The Ysra mark. Store images next to the page that uses them, or in `docs/assets/`.
///

## Links to headings

Every heading has an anchor: hover it and click the `#` to copy a link. Link to
a heading on another page with its slug — for example
[the wallet ledger](../api/account/wallet.md#list-ledger-entries). The build
fails if the anchor does not exist.
