# API de scripting Lua de pxstud.io — Color

> Parte de la referencia de scripting Lua de pxstud.io, cuya introducción (https://pxstud.io/es/docs/scripting.md) explica sus convenciones. Los grupos de opciones y los tipos a los que remite están en https://pxstud.io/es/docs/scripting/option-groups.md y https://pxstud.io/es/docs/scripting/types.md. Todo en un solo archivo (en inglés): https://pxstud.io/llms-full.txt. El índice de todo el sitio (en inglés): https://pxstud.io/llms.txt.

### Color
Matemática del color sin analizar hexadecimales a mano ni mezclar RGB a mano. Los colores de entrada son cadenas "#rrggbb" / "#rrggbbaa" o tablas { r, g, b, a } (0-255, a opcional); los colores de salida son tablas { r, g, b, a } salvo que el nombre indique hex. Mezclar y ajustar usan OKLab por defecto, un espacio perceptual en el que pasos iguales se ven iguales; `space` puede ser "oklab", "oklch", "rgb" o "hsl". Los resultados se limitan a sRGB reduciendo la croma, así que el tono y la luminosidad se mantienen. Las listas (ramp, shades) se construyen en una sola llamada.

#### `app.color.adjust(c, opts?)` — pura
Cambia la luminosidad, la croma, el tono, la saturación o el alfa de un color, de forma absoluta o relativa. El resultado se limita a la gama sRGB reduciendo la croma (se conservan la luminosidad y el tono), no recortando canales.

- `c` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `opts` (table, opcional) — Las claves absolutas establecen un valor; las claves con prefijo d lo suman (primero se aplica el valor establecido y después el delta). Las claves omitidas conservan el valor del propio color.
  - `lightness` (number) — Establece la luminosidad: L de OKLab/OKLCH (0 negro - 1 blanco), o la luminosidad HSL con space = "hsl".
  - `chroma` (number ≥ 0) — Establece la croma OKLCH (colorido, 0 = gris; sRGB llega a cerca de 0.32). No disponible con space = "hsl".
  - `hue` (number) — Establece el ángulo del tono en grados (da la vuelta en 360).
  - `saturation` (number 0–1) — Establece la saturación 0-1: saturación HSL con space = "hsl"; en otro caso, la croma como fracción de la máxima que sRGB permite con esa luminosidad y ese tono.
  - `alpha` (number 0–255) — Establece el alfa, 0-255.
  - `dLightness` (number) — Suma a la luminosidad (un valor negativo oscurece).
  - `dChroma` (number) — Suma a la croma.
  - `dHue` (number) — Gira el tono estos grados.
  - `dSaturation` (number) — Suma a la saturación (escala 0-1).
  - `dAlpha` (number) — Suma al alfa (escala 0-255).
  - `space` (string; predeterminado "oklab") — "oklab" | "oklch" (aquí es lo mismo) | "hsl". "rgb" no tiene eje de luminosidad ni de tono y se rechaza.

Devuelve (table): { r, g, b, a }, cada uno 0-255.

#### `app.color.contrast(a, b)` — pura
Relación de contraste WCAG entre dos colores (se ignora el alfa), de 1 (idénticos) a 21 (negro sobre blanco). 4.5 es el mínimo habitual para texto legible.

- `a` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `b` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.

Devuelve (number): La relación, 1-21.

#### `app.color.darken(c, amount, space?)` — pura
Atajo de app.color.adjust(c, { dLightness = -amount }).

- `c` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `amount` (number) — Se resta a la luminosidad (unidades de L de OKLab, 0-1).
- `space` (string, opcional) — Dónde se mide la luminosidad: "oklab" (predeterminado), "oklch" o "hsl".

Devuelve (table): { r, g, b, a }, cada uno 0-255.

#### `app.color.distance(a, b)` — pura
Distancia euclidiana entre dos colores en OKLab (se ignora el alfa). 0 = idénticos; de negro a blanco es 1; alrededor de 0.02 apenas se nota.

- `a` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `b` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.

Devuelve (number): La distancia, 0 o más.

#### `app.color.hex(c, withAlpha?)` — pura
Un color como cadena hexadecimal en minúsculas.

- `c` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `withAlpha` (boolean, opcional) — true para "#rrggbbaa"; por defecto "#rrggbb".

Devuelve (string): "#rrggbb", o "#rrggbbaa" con withAlpha.

#### `app.color.lighten(c, amount, space?)` — pura
Atajo de app.color.adjust(c, { dLightness = amount }).

- `c` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `amount` (number) — Se suma a la luminosidad (unidades de L de OKLab, 0-1).
- `space` (string, opcional) — Dónde se mide la luminosidad: "oklab" (predeterminado), "oklch" o "hsl".

Devuelve (table): { r, g, b, a }, cada uno 0-255.

#### `app.color.mix(a, b, t, space?)` — pura
Mezcla dos colores (también el alfa) en un espacio perceptual; OKLab por defecto, que evita los puntos medios apagados de la mezcla en RGB.

- `a` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `b` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `t` (number) — 0 = a, 1 = b; se limita a 0-1.
- `space` (string, opcional) — Espacio de interpolación: "oklab" (predeterminado), "oklch" (el tono recorre el camino corto), "rgb" o "hsl".

Devuelve (table): { r, g, b, a }, cada uno 0-255.

#### `app.color.nearest(c, palette)` — pura
La entrada de la paleta más cercana a c por distancia OKLab (se ignora el alfa). Los empates van a la entrada anterior.

- `c` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `palette` (table) — Una lista de colores no vacía.

Devuelve (number): El índice en palette, empezando en 1.

#### `app.color.parse(c)` — pura
Normaliza cualquier color aceptado a { r, g, b, a } (a = 255 cuando la entrada no lo trae).

- `c` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.

Devuelve (table): { r, g, b, a }, cada uno 0-255.

#### `app.color.ramp(stops, n, space?)` — pura
Un degradado muestreado en una lista de n colores, del primer al último punto, con ambos extremos incluidos. Una sola llamada sin importar n.

- `stops` (table) — Una lista de colores, o de { color =, pos = } con pos 0-1 (los puntos sin pos se reparten por igual). Necesita al menos uno.
- `n` (number) — Cuántos colores devolver, 1-4096. 1 devuelve el primer punto.
- `space` (string, opcional) — Espacio de interpolación: "oklab" (predeterminado), "oklch" (el tono recorre el camino corto), "rgb" o "hsl".

Devuelve (table): Una lista de n colores { r, g, b, a }.

#### `app.color.shades(base, n, opts?)` — pura
Una lista de n colores de la sombra a la luz alrededor de base, para sombrear. La base está en el índice floor(n / 2) + 1 (el medio si n es impar) y se devuelve exactamente. Con f yendo de -1 (más oscuro) pasando por 0 (base) hasta +1 (más claro), el tono i tiene luminosidad OKLab L + f * spread / 2 (limitada a 0-1), tono H + f * hueShift y croma C * (1 - 0.4 * f^2), de modo que los extremos se queden dentro de sRGB (lo que aún quede fuera pierde croma, nunca luminosidad). Se conserva el alfa. La luminosidad es monótona a lo largo de la lista.

- `base` (color) — Un color: "#rrggbb", "#rrggbbaa" o { r, g, b, a }.
- `n` (number) — Cuántos colores devolver, 1-4096.
- `opts` (table, opcional)
  - `spread` (number; predeterminado 0.5) — Rango total de luminosidad OKLab, de la sombra a la luz (la base es el centro: la mitad del rango hacia abajo, la mitad hacia arriba). Se limita a 0-1.
  - `hueShift` (number; predeterminado 8) — Grados que gira el tono en los extremos: las sombras en -hueShift, las luces en +hueShift, escalando linealmente hasta 0 en la base.

Devuelve (table): Una lista de n colores { r, g, b, a }, del más oscuro al más claro.
