# @zakkster/lite-gradient
> Zero-GC OKLCH gradient generator. N-stop perceptually uniform gradients.

## Install
npm i @zakkster/lite-gradient

## Import
import { Gradient, monochromeGradient, gradientMonoWarm, gradientSunset } from '@zakkster/lite-gradient';

## Key Facts
- N-stop OKLCH gradients (perceptually uniform, no gray dead zones)
- at(t, out): caller-owned output object (zero-GC)
- css(t): CSS oklch() string (allocates - use for setup)
- palette(count): array of CSS color strings
- sampleArray(out, count): fill Float32Array LUT (zero-GC)
- toLinear(ctx, x0,y0,x1,y1): Canvas2D linear gradient
- toRadial(ctx, cx,cy,r): Canvas2D radial gradient
- toCssLinear(angle?), toCssRadial(): CSS gradient strings
- 7 presets: Sunset, Ocean, Fire, Neon, Grey, MonoWarm, MonoCool
- Dependencies: @zakkster/lite-color, @zakkster/lite-lerp

## Monochrome (v1.1.0)
monochromeGradient(base, { mode?, range?, stops? }) -> Gradient
  Tone-on-tone gradient from a single base OKLCH color. Chroma and hue
  held constant; L varies across `range`. mode='tinted' (default) retains
  base c/h; mode='grayscale' forces c=0. range=[lo,hi] with 0<=lo<hi<=1
  (default [0,1]). stops=integer>=2 (default 2 endpoints; smooth OKLCH
  interpolation makes higher counts visually identical for continuous
  rendering; use 11 or 12 for anchored export stop placement).

  Pairs with @zakkster/lite-hueforge's monochromeScale(base, opts) which
  returns discrete Radix-style step arrays; monochromeGradient returns a
  continuous Gradient ready for canvas/CSS emission.

Presets:
  gradientMonoWarm - warm sepia (photography/editorial classic)
  gradientMonoCool - cool blue-grey (client-safe neutral)

## Usage
const g = new Gradient([
    { l: 0.3, c: 0.15, h: 270 },
    { l: 0.9, c: 0.12, h: 60 },
]);
const out = { l: 0, c: 0, h: 0 };
g.at(0.5, out); // zero-GC sampling
const css = g.css(0.5); // setup only

// Monochrome from a brand color
const brand = monochromeGradient({ l: 0.5, c: 0.08, h: 245 });
ctx.fillStyle = brand.toLinear(ctx, 0, 0, 800, 600);
ctx.fillRect(0, 0, 800, 600);
