# `Incant.Surface`
[🔗](https://github.com/elixir-vibe/incant/blob/v0.1.1/lib/incant/surface.ex#L1)

Common envelope for top-level Incant admin surfaces.

Resources, dashboards, datasets, tools, and future admin concepts are wrapped
in a surface envelope. The envelope owns cross-cutting identity used by routes,
navigation, public contracts, and remote transports. The `spec` field contains
the kind-specific metadata.

# `kind`

```elixir
@type kind() :: :resource | :dashboard | :dataset | atom()
```

# `t`

```elixir
@type t() :: %Incant.Surface{
  id: String.t(),
  kind: kind(),
  module: module(),
  opts: keyword(),
  spec: struct(),
  title: String.t()
}
```

# `id`

```elixir
@spec id(
  module(),
  keyword()
) :: String.t()
```

Builds a stable surface id from explicit opts or module naming convention.

# `title`

```elixir
@spec title(module(), keyword(), String.t() | nil) :: String.t()
```

Builds a human title from explicit opts, metadata title, or module name.

---

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