# Page head

The screen's title, an optional line under it and its actions, above the body.

The page head names the screen in its one h1 and can add a short line that says what the screen is for. Actions sit at its end as buttons; keep one solid primary action and make the rest outlined or ghost. The shell writes it at the top of the main stage, before the body.

## Use it

Web:

```rust
use ocean_ui_core::{Button, Variant};
let (title, sub) = ("Tickets".to_string(), Some("Requests waiting on the desk".to_string()));
let actions = vec![Button::new("New ticket", Variant::Solid).href("/tickets/new")];
```

Native:

```rust
use ocean_ui_native::shell::Shell;
let sub = Some("This window: sidebar, top bar, page head, menu bar.".into());
Shell { title: "Shell".into(), sub, actions: Vec::new(), ..shell }.show(ui, &mut reg, |ui| ui.label("…"))
```

Cargo feature `shell`; since 2026-10-29.
In App UI the `heading` block draws it ([heading](/ui/blocks/heading.md)).

## Props

| Name | Type | Default | What |
|---|---|---|---|
| `title` | `String` | `—` | The screen's name, its one h1. |
| `sub` | `Option<String>` | `None` | One line under the title. |
| `actions` | `Vec<Button>` | `—` | The buttons at the head's end, in the order given; none leaves the end empty. |

On the Mac: ![Page head, dark](/ui/native/shell-dark.png) ![Page head, light](/ui/native/shell-light.png)

## Examples

### Title, sub and actions

Every page has a title, one sentence and its ranked actions.

```rust
let shell = Shell {
    app_name: "Service desk",
    version: "0.8.8".into(),
    nav: nav(),
    here: "queue",
    crumb: vec![
        Crumb { text: "Service desk".into(), href: Some("#queue".into()) },
        Crumb { text: "Queue".into(), href: None },
    ],
    title: "Queue".into(),
    sub: Some("Every ticket open now".into()),
    actions: vec![Button::new("Build an agent", Variant::Solid).href("#build")],
    status: None,
};
out.push_str(&page(&shell));
```

### Two actions

One primary; the rest outlined.

```rust
let actions = vec![
    Button::new("Export", Variant::Outline).href("#export"),
    Button::new("Build an agent", Variant::Solid).href("#build"),
];
let shell = Shell { actions,..desk() };
out.push_str(&page(&shell));
```

### Title only

A page with nothing to do but read needs no actions.

```rust
let shell = Shell {
    here: "cost",
    title: "Cost control".into(),
    sub: None,
    actions: Vec::new(),
    ..desk()
};
out.push_str(&page(&shell));
```

## Accessibility

- The title is the screen's only h1, and the cards below it use h2.
- Actions keep their own names and states, such as aria-busy on a busy button.
- The skip link lands on the main stage, so the page head is the first thing read after it.

## Related

- [Button](/ui/components/button.md)
- [Breadcrumb](/ui/components/breadcrumb.md)
- [Top bar](/ui/components/topbar.md)
- [Card](/ui/components/card.md)
