---
name: app-shell
user-invocable: true
description: >-
  How to lay out the shell of an Adom single-page app: a full-height column with a fixed 44px header,
  a scrollable body that fills the rest, and an optional footer or status bar, built so it sizes
  correctly and reshapes responsively instead of overflowing or collapsing. Covers the full-height
  flex column, the intrinsic-sizing traps (min-height:0, minmax(0,1fr), position:fixed on the app
  root), where HUDs and toasts mount, fluid panels and split layouts, and the footer / status-bar
  convention. Read BEFORE laying out a new app or when an app overflows, scrolls the whole page, or a
  canvas will not fill its pane. Trigger words: app shell, app layout, single page app layout, SPA
  layout, full height layout, fluid layout, header body footer, status bar, footer, app footer,
  scroll container, min-height 0, minmax 0 1fr, canvas wont fill, page scrolls, sticky header layout.
---

# The app shell

The shell is the frame every Adom app shares: a header at the top, content that fills the rest, and
an optional footer. Get the shell right and everything inside it sizes correctly; get it wrong and
the page scrolls as a whole, a canvas refuses to fill its pane, or a panel overflows the screen.

## The full-height column

```
.app                 position: fixed; inset: 0; display: flex; flex-direction: column;
  .app-header        height: 44px; flex: 0 0 auto;        (see adom-app-header)
  .app-body          flex: 1 1 auto; min-height: 0; overflow: auto / a grid of panes
  .app-footer        flex: 0 0 auto;  (optional status bar)
```

```css
.app    { position: fixed; inset: 0; display: flex; flex-direction: column;
          background: #0d1117; color: #e6edf3; }
.app-header { flex: 0 0 44px; }
.app-body   { flex: 1 1 auto; min-height: 0; }   /* min-height:0 is load-bearing */
.app-footer { flex: 0 0 auto; }
```

### The intrinsic-sizing traps (these cause most layout bugs)

- **`min-height: 0` on the flex body.** Without it a flex child refuses to shrink below its content,
  so a tall child makes the whole app overflow and the page scrolls. This single line fixes the most
  common "the whole page scrolls instead of the panel" bug.
- **`minmax(0, 1fr)` in grids.** A grid track defaults to `min-content`, which will not shrink. Use
  `minmax(0, 1fr)` so a pane (especially one holding a canvas) can actually size down.
- **`position: fixed` on `.app`,** anchored to `inset: 0`, so the shell is exactly the viewport and
  nothing relies on document flow. For a canvas, sync its pixel size to the pane's client size on
  resize, do not assume CSS size equals backing-store size.

## The body: fluid panes and splits

- A single scroll region uses `overflow: auto` on `.app-body`.
- A multi-pane layout uses CSS grid with `minmax(0, 1fr)` tracks and a draggable splitter. Keep
  split ratios between 0.1 and 0.9 and persist them.
- The body reshapes responsively: side-by-side panes on desktop become a single column or tabs on a
  phone (see `responsive-ui`).

## The footer / status bar

A footer is optional. When present it is a thin status bar, not a second toolbar:

- One row, muted, for ambient state: connection status, current mode, counts, a save indicator, the
  zoom level. Monospace for numeric/data readouts (see the type rules in `adom-ui-design`).
- It does not hold primary actions (those live in the header's actions zone or a bottom bar on
  mobile). It must never grow or wrap.
- `flex: 0 0 auto`, at `--z-toolbar: 80`.

## Where overlays mount

- HUDs (`floating-windows`) float over `.app-body` at `--z-hud: 50`.
- Toasts (`toasts`) mount at the bottom center at `--z-toast: 400`.
- The global tooltip div (`tooltips`) is appended to `<body>`, outside the shell, at 99999.

## Related skills

`adom-app-header` (the header), `responsive-ui` (how the shell reshapes), `floating-windows`,
`toasts`, `tooltips`, and `adom-ui-design` (the hub).
