# `DocShell.Presentation.Renderer`
[🔗](https://github.com/futhr/doc_shell/blob/v2.0.0/lib/doc_shell/presentation/renderer.ex#L1)

Defines the boundary between a portable site and a concrete renderer.

A renderer turns validated `Page` and `Site` values into output and declares
the capabilities that output can honestly provide. `admit/3` compares those
capabilities with requirements derived from page content before rendering.
Unsupported essential content fails; optional content is admitted only when
its declared fallback still matches the projected page.

Renderers receive inert values and local logical assets. Authorization,
application sessions, routing policy, deployment, and source collection stay
with the host or projector. This behaviour therefore works for a hosted UI
and a no-server static build without making either one the core abstraction.

# `assets`

```elixir
@callback assets(DocShell.Presentation.Site.t(), keyword()) ::
  {:ok, [DocShell.Presentation.Asset.t()]} | {:error, term()}
```

Returns local assets needed by this site generation.

# `capabilities`

```elixir
@callback capabilities() :: DocShell.Presentation.Renderer.Capabilities.t()
```

Returns the renderer's normalized capability declaration.

# `render_not_found`

```elixir
@callback render_not_found(
  DocShell.Presentation.Site.t(),
  DocShell.Presentation.Renderer.Context.t()
) ::
  {:ok, iodata()} | {:error, term()}
```

Renders the site's not-found page.

# `render_page`

```elixir
@callback render_page(
  DocShell.Presentation.Page.t(),
  DocShell.Presentation.Renderer.Context.t()
) ::
  {:ok, iodata()} | {:error, term()}
```

Renders one admitted page.

# `admit`

```elixir
@spec admit(
  DocShell.Presentation.Page.t(),
  DocShell.Presentation.Renderer.Capabilities.t(),
  :hosted | :static
) :: :ok | {:error, term()}
```

Checks that a renderer can satisfy one page in an output mode.

# `reserved_features`

```elixir
@spec reserved_features() :: [String.t()]
```

Returns the closed DSH.01 feature identifiers reserved by DocShell.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
