# `ExRatatui.Theme`
[🔗](https://github.com/mcass19/ex_ratatui/blob/v0.10.1/lib/ex_ratatui/theme.ex#L1)

Named-slot color palette for TUI apps.

A `%Theme{}` is a pure data struct — a map from semantic slot names
(`:accent`, `:border`, `:success`, …) to `t:ExRatatui.Style.color/0`
values. Apps build `%Style{}` values from it via the helpers below
(`border_style/2`, `text_style/2`, `selection_style/1`) or by
destructuring slots directly into widget fields.

This is "Layer A" of the theming work: pure data the app threads
through its render code by hand. There is no automatic widget
injection — Block borders don't magically pick up `theme.border`
unless the app passes it in. A later "Layer B" may add an opt-in
pass that merges theme defaults into widget structs at render time;
Layer A stays explicit and dependency-free.

## Slots

  * `:primary` — main brand color (titles, highlighted headers)
  * `:accent` — interactive / focused / selected elements
  * `:border` — default border color for unfocused panels
  * `:border_focused` — border color for the focused panel
  * `:surface` — primary background; `nil` means "let the terminal
    decide" and works on both light and dark terminals
  * `:surface_alt` — secondary background (alt rows in tables,
    striped lists, raised panels)
  * `:text` — default foreground for body text
  * `:text_dim` — secondary foreground (hints, placeholders,
    disabled controls)
  * `:success` / `:warning` / `:danger` — status messages and
    severity indicators

Every slot accepts the full `t:ExRatatui.Style.color/0` shape:
named atoms (`:cyan`, `:dark_gray`), `{:rgb, r, g, b}`,
`{:indexed, n}`, or `nil`. Slots default to `nil`, meaning "fall
back to the terminal default" — apps that don't want to depend on
any particular palette can drop unused slots.

## Composing with widgets

    theme = ExRatatui.Theme.default()

    %ExRatatui.Widgets.Block{
      title: "Search",
      borders: [:all],
      border_style: ExRatatui.Theme.border_style(theme, focused: focused?)
    }

    %ExRatatui.Widgets.List{
      items: results,
      highlight_style: ExRatatui.Theme.selection_style(theme)
    }

## Picking a theme

Two starter constructors ship in the box:

  * `default/0` — terminal-respecting dark-friendly palette
    (cyan accent, transparent surface)
  * `light/0` — same shape with darker text and a light surface,
    suitable for light terminal themes

Apps with stricter brand requirements compose their own:

    %ExRatatui.Theme{
      primary: {:rgb, 88, 28, 135},
      accent: {:rgb, 245, 158, 11},
      border: :gray,
      border_focused: {:rgb, 245, 158, 11},
      text: :white,
      text_dim: :gray,
      success: :green,
      warning: :yellow,
      danger: :red
    }

# `t`

```elixir
@type t() :: %ExRatatui.Theme{
  accent: ExRatatui.Style.color() | nil,
  border: ExRatatui.Style.color() | nil,
  border_focused: ExRatatui.Style.color() | nil,
  danger: ExRatatui.Style.color() | nil,
  primary: ExRatatui.Style.color() | nil,
  success: ExRatatui.Style.color() | nil,
  surface: ExRatatui.Style.color() | nil,
  surface_alt: ExRatatui.Style.color() | nil,
  text: ExRatatui.Style.color() | nil,
  text_dim: ExRatatui.Style.color() | nil,
  warning: ExRatatui.Style.color() | nil
}
```

# `border_style`

```elixir
@spec border_style(
  t(),
  keyword()
) :: ExRatatui.Style.t()
```

Builds a border `%Style{}` from a theme.

Accepts `focused: true` to swap in `:border_focused`. Defaults to the
unfocused `:border` slot.

## Examples

    iex> theme = ExRatatui.Theme.default()
    iex> ExRatatui.Theme.border_style(theme)
    %ExRatatui.Style{fg: :gray, bg: nil, modifiers: []}
    iex> ExRatatui.Theme.border_style(theme, focused: true)
    %ExRatatui.Style{fg: :cyan, bg: nil, modifiers: []}

# `default`

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

Returns a terminal-respecting dark-friendly default theme.

Surfaces are `nil` so the terminal's own background shows through —
works on both light and dark terminal themes without forcing one.
Accent is cyan, borders are gray with cyan-on-focus, status uses the
conventional green / yellow / red triad.

## Examples

    iex> theme = ExRatatui.Theme.default()
    iex> theme.accent
    :cyan
    iex> theme.surface
    nil

# `light`

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

Returns a light-terminal-friendly variant of `default/0`.

Text is dark, surface is white, accent stays cyan but borders shift
to dark_gray for contrast on a light background.

## Examples

    iex> theme = ExRatatui.Theme.light()
    iex> theme.text
    :black
    iex> theme.surface
    :white

# `selection_style`

```elixir
@spec selection_style(t()) :: ExRatatui.Style.t()
```

Builds a selection-highlight `%Style{}` from a theme.

The convention is a reversed-style pop: the theme's `:surface` color
becomes the foreground, the `:accent` becomes the background. Use on
List `:highlight_style`, Table `:highlight_style`, selected Tabs,
etc.

## Examples

    iex> theme = ExRatatui.Theme.default()
    iex> ExRatatui.Theme.selection_style(theme)
    %ExRatatui.Style{fg: nil, bg: :cyan, modifiers: []}

# `text_style`

```elixir
@spec text_style(
  t(),
  keyword()
) :: ExRatatui.Style.t()
```

Builds a body-text `%Style{}` from a theme.

Accepts `dim: true` to use the `:text_dim` slot (hints, placeholders,
disabled). The background is always `theme.surface`, which is `nil`
in the default theme.

## Examples

    iex> theme = ExRatatui.Theme.default()
    iex> ExRatatui.Theme.text_style(theme)
    %ExRatatui.Style{fg: :white, bg: nil, modifiers: []}
    iex> ExRatatui.Theme.text_style(theme, dim: true)
    %ExRatatui.Style{fg: :gray, bg: nil, modifiers: []}

---

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