# `Drafter.Theme`
[🔗](https://github.com/jaman/drafter/blob/main/lib/drafter/theming/theme.ex#L1)

Theme definition and built-in theme library for TUI applications.

A theme is a `%Drafter.Theme{}` struct containing named RGB color slots covering
UI surfaces, semantic colors (primary, secondary, accent, warning, error, success),
text variants, cursor colors, and a `syntax` map for code highlighting. The framework
ships with thirteen ready-to-use themes accessible via `available_themes/0` and
`get_theme/1`, including `"textual-dark"`, `"nord"`, `"dracula"`, `"monokai"`,
`"tokyo-night"`, and `"catppuccin-mocha"`.

# `rgb`

```elixir
@type rgb() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}
```

# `t`

```elixir
@type t() :: %Drafter.Theme{
  accent: rgb(),
  accent_muted: rgb(),
  background: rgb(),
  block_hover: rgb(),
  border: rgb(),
  cursor: %{
    block_cursor: rgb(),
    block_cursor_foreground: rgb(),
    block_cursor_blurred: rgb()
  },
  dark: boolean(),
  error: rgb(),
  error_muted: rgb(),
  foreground: rgb(),
  name: String.t(),
  panel: rgb(),
  primary: rgb(),
  primary_muted: rgb(),
  secondary: rgb(),
  secondary_muted: rgb(),
  success: rgb(),
  success_muted: rgb(),
  surface: rgb(),
  syntax: %{required(atom()) =&gt; rgb()},
  text_accent: rgb(),
  text_disabled: rgb(),
  text_error: rgb(),
  text_muted: rgb(),
  text_primary: rgb(),
  text_secondary: rgb(),
  text_success: rgb(),
  text_warning: rgb(),
  warning: rgb(),
  warning_muted: rgb()
}
```

# `available_themes`

```elixir
@spec available_themes() :: %{required(String.t()) =&gt; t()}
```

Every built-in theme, keyed by the name `get_theme/1` takes.

## Examples

    iex> Drafter.Theme.available_themes() |> Map.keys() |> Enum.sort() |> hd()
    "catppuccin-mocha"

    iex> Drafter.Theme.available_themes() |> map_size()
    13

# `catppuccin_mocha_theme`

```elixir
@spec catppuccin_mocha_theme() :: t()
```

The built-in `"catppuccin-mocha"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.catppuccin_mocha_theme().name
    "catppuccin-mocha"

# `classic_theme`

```elixir
@spec classic_theme() :: t()
```

The built-in `"classic"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.classic_theme().name
    "classic"

# `dark_theme`

```elixir
@spec dark_theme() :: t()
```

The built-in `"textual-dark"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.dark_theme().name
    "textual-dark"

# `default_syntax_colors`

```elixir
@spec default_syntax_colors(t()) :: %{required(atom()) =&gt; rgb()}
```

The syntax-highlighting palette derived from a theme's semantic colours.

Keys: `:keyword`, `:keyword_builtin`, `:type`, `:function`, `:function_builtin`,
`:variable`, `:string`, `:string_special`, `:number`, `:operator`, `:comment` and
`:default`. The mapping is currently the same for dark and light themes, but a
theme whose `:dark` field is neither `true` nor `false` raises
`FunctionClauseError`.

# `dracula_theme`

```elixir
@spec dracula_theme() :: t()
```

The built-in `"dracula"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.dracula_theme().name
    "dracula"

# `get_color`

```elixir
@spec get_color(t(), {:syntax, atom()} | atom()) :: term() | nil
```

Look a colour up on a theme by slot name.

`{:syntax, key}` reads the theme's syntax map. A plain atom reads the struct field
of that name and, when that field is `nil`, falls back to the theme's `:cursor`
map — so `:block_cursor` and friends resolve without naming the map. Returns `nil`
when neither carries the name. Any struct field is reachable this way, including
the non-colour `:name` and `:dark`.

## Examples

    iex> Drafter.Theme.get_color(Drafter.Theme.nord_theme(), :primary)
    {136, 192, 208}

    iex> Drafter.Theme.get_color(Drafter.Theme.nord_theme(), {:syntax, :no_such_token})
    nil

    iex> Drafter.Theme.get_color(Drafter.Theme.nord_theme(), :no_such_slot)
    nil

# `get_theme`

```elixir
@spec get_theme(String.t()) :: t() | nil
```

The built-in theme called `name`, or `nil` when there is no such theme.

## Examples

    iex> Drafter.Theme.get_theme("nord").dark
    true

    iex> Drafter.Theme.get_theme("no-such-theme")
    nil

# `gruvbox_dark_theme`

```elixir
@spec gruvbox_dark_theme() :: t()
```

The built-in `"gruvbox-dark"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.gruvbox_dark_theme().name
    "gruvbox-dark"

# `gruvbox_light_theme`

```elixir
@spec gruvbox_light_theme() :: t()
```

The built-in `"gruvbox-light"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.gruvbox_light_theme().name
    "gruvbox-light"

# `light_theme`

```elixir
@spec light_theme() :: t()
```

The built-in `"textual-light"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.light_theme().name
    "textual-light"

# `monokai_theme`

```elixir
@spec monokai_theme() :: t()
```

The built-in `"monokai"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.monokai_theme().name
    "monokai"

# `mute_color`

```elixir
@spec mute_color(rgb() | nil | term()) :: rgb() | nil | term()
```

A desaturated version of an `{r, g, b}` colour.

Each channel is moved halfway towards the mean of the three, which keeps the
colour's brightness and halves its saturation. A grey stays exactly as it was.

`nil` passes through as `nil`, and any other term is returned unchanged.

## Examples

    iex> Drafter.Theme.mute_color({200, 100, 0})
    {150, 100, 50}

    iex> Drafter.Theme.mute_color({80, 80, 80})
    {80, 80, 80}

    iex> Drafter.Theme.mute_color(nil)
    nil

# `nord_theme`

```elixir
@spec nord_theme() :: t()
```

The built-in `"nord"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.nord_theme().name
    "nord"

# `retro_theme`

```elixir
@spec retro_theme() :: t()
```

The built-in `"retro"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.retro_theme().name
    "retro"

# `solarized_dark_theme`

```elixir
@spec solarized_dark_theme() :: t()
```

The built-in `"solarized-dark"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.solarized_dark_theme().name
    "solarized-dark"

# `solarized_light_theme`

```elixir
@spec solarized_light_theme() :: t()
```

The built-in `"solarized-light"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.solarized_light_theme().name
    "solarized-light"

# `tokyo_night_theme`

```elixir
@spec tokyo_night_theme() :: t()
```

The built-in `"tokyo-night"` theme, with its syntax map filled in from
`default_syntax_colors/1`.

## Examples

    iex> Drafter.Theme.tokyo_night_theme().name
    "tokyo-night"

---

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