# `Plushie.Type.Gradient`
[🔗](https://github.com/plushie-ui/plushie-elixir/blob/v0.7.2/lib/plushie/type/gradient.ex#L1)

Gradient type for container and style backgrounds.

Build gradients with `linear/3`:

    Plushie.Type.Gradient.linear({0, 0}, {100, 100}, [
      {0.0, "#ff0000"},
      {0.5, "#00ff00"},
      {1.0, "#0000ff"}
    ])

Or from an angle with `linear_from_angle/2`:

    Plushie.Type.Gradient.linear_from_angle(90, [
      {0.0, "#ff0000"},
      {1.0, "#0000ff"}
    ])

Stop colors accept any form `Plushie.Type.Color.cast/1` supports
(named atoms, hex strings, RGBA maps). They are normalized to
canonical hex strings during construction.

## Wire format

Uses the same coordinate-based format as `Plushie.Canvas.Gradient`:

    %{
      type: "linear",
      start: [0, 0],
      end: [100, 100],
      stops: [[0.0, "#ff0000"], [1.0, "#0000ff"]]
    }

# `stop`

```elixir
@type stop() :: {float(), String.t()}
```

A gradient color stop: `{offset, color}` where offset is 0.0-1.0.

# `stop_color`

```elixir
@type stop_color() :: Plushie.Type.Color.input()
```

Color input for gradient stops: any form `Color.cast/1` supports.

# `t`

```elixir
@type t() :: %Plushie.Type.Gradient{
  from: {number(), number()},
  stops: [stop()],
  to: {number(), number()}
}
```

# `cast`

Validates a gradient value.

Accepts `%Gradient{}` structs directly, or plain maps with
`from`/`to` coordinate tuples and `stops`.

# `linear`

```elixir
@spec linear(
  from :: {number(), number()},
  to :: {number(), number()},
  stops :: [{number(), stop_color()}]
) :: t()
```

Creates a linear gradient between two coordinate points.

# `linear_from_angle`

```elixir
@spec linear_from_angle(angle :: number(), stops :: [{number(), stop_color()}]) :: t()
```

Creates a linear gradient from an angle (degrees) and stops.

The angle is converted to start/end coordinates on a unit square
(0,0 to 1,1). Use this when you want angle-based gradients without
computing coordinates manually.

---

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