Package com.smartgwt.client.docs

# Interface ColorOverview

public interface ColorOverview

### Color Overview

### Color Spaces

Smart GWT's `Colors` class works in three color spaces, each with different strengths. All three are always available on every `Color` object - conversion is automatic.

- RGB (`Color.r`, `Color.g`, `Color.b`) - the hardware color space. Each channel is 0-255. Best for: direct pixel-level work, matching exact hex values, and interop with legacy APIs. Poor for manipulation - "add 20 to green" is not a meaningful perceptual operation.
- HSL (`Color.h`, `Color.s`, `Color.l`) - separates hue (color), saturation (intensity), and lightness. Hue is 0-360 degrees, s and l are 0-100. Intuitive for humans but not perceptually uniform - 50% lightness in yellow looks far brighter than 50% lightness in blue.
- oklch (`Color.ok_L`, `Color.ok_C`, `Color.ok_h`) - a perceptually uniform color space where equal numeric steps produce equal perceived visual differences. L is 0-1 (lightness), C is ~0-0.4 (chroma/saturation), h is 0-360 (hue). Best for: color manipulation, palette generation, accessibility contrast checking. All `adjust()` operations work in oklch. Note that oklch hue angles differ from HSL hue angles (red is ~30 in oklch vs 0 in HSL) because oklch redistributes hues for perceptual uniformity.

### Color Formats and Conversion

The `ColorFormat` type covers four CSS string representations: `"hex"`, `"rgb"`, `"hsl"`, and `"oklch"`. Key conversion methods:

- `Colors.getColor()` - parse any color string or object into a full `Color` with all three color spaces pre-computed
- `Colors.getString()` - convert to a CSS string in any format
- `Colors.getValues()` - extract raw numeric components in one color space
- `Colors.isColor()` - validate without conversion
- `Colors.getFormat()` - detect the format of a color string

`Colors.getColor()` always returns a Color object (never null). If the input cannot be parsed, `isValid()` returns false and properties default to black.

### Color Manipulation

All manipulation methods operate in oklch for perceptual uniformity and return new Color objects or CSS strings.

- `Colors.adjust()` - general-purpose multi-axis adjustment (lightness, saturation, hue, alpha); the foundation for all other manipulation methods
- `Colors.lighten()` / `Colors.darken()` - perceptual lightness (oklch L)
- `Colors.brighten()` / `Colors.dim()` - combined lightness + chroma boost/cut
- `Colors.saturate()` / `Colors.desaturate()` - chroma (oklch C)
- `Colors.complement()` / `Colors.spin()` - hue rotation
- `Colors.flatten()` - composite semi-transparent color to opaque over a background
- `Colors.getAlpha()` / `Colors.setAlpha()` - read or change the alpha channel

### Inspection

- `Colors.isDark()` - perceptual light-vs-dark test (oklch L < 0.6)
- `Colors.contrast()` - approximate perceptual contrast ratio between two colors
- `Colors.distance()` - perceptual color difference in oklab space
- `Colors.equals()` - same-color comparison across formats

### CSS Color Relationships

Modern CSS supports derived colors - colors defined as transformations of a base color using CSS Relative Color Syntax (RCS). For example, a skin might define a "hover highlight" as "10% lighter than the accent color": `oklch(from var(--accent) calc(l + 0.10) c h)`. When the user changes the accent color, the hover highlight updates automatically because it is defined as a relationship rather than a fixed hex value.

Four methods form a pipeline for working with these color relationships:

- `Colors.resolveCSS()` - resolve any CSS color expression (including `var()` references) to a flat Color via the browser's CSS engine
- `Colors.parseRelationship()` - extract the structure of an RCS expression (origin, color space, channel deltas) without evaluating it
- `Colors.describeRelationship()` - given a base and derived color, compute what changed (e.g. "lightened by 0.15 in oklch")
- `Colors.generateCSS()` - produce an oklch RCS expression from a relationship descriptor, ready for CSS output

Typical round-trip: a skin config stores `oklch(from var(--accent) calc(l + 0.15) c h)`. On load, `parseRelationship()` extracts the origin and deltas. The Skin Editor resolves `var(--accent)` via `resolveCSS()` to show a color swatch. If the user changes the accent, `generateCSS()` rebuilds the RCS expression with the same relationship but the new origin.

`Colors.getColor()` can also resolve RCS expressions with literal color origins (hex, named colors, rgb()/hsl()/oklch() calls) in pure JavaScript - no DOM required. For expressions that reference CSS custom properties via `var()`, `Colors.resolveCSS()` is needed to resolve them through the browser's CSS engine.

Channel ranges in RCS follow the native CSS scale for each color space: r/g/b are 0-255, h is degrees, s/l are 0-100 (HSL), and oklch L is 0-1, C is ~0-0.4, h is 0-360. Each channel position in the RCS expression can be a bare keyword (`r`), a `calc()` expression (`calc(r - 50)`), or a `max()`/`min()` wrapper for clamping (`max(calc(s - 80), 0)`).

### Palette and Harmony

Methods for generating sets of related colors:

- `Colors.colorScale()` - multi-step gradient between two endpoints
- `Colors.mix()` - blend two colors at a given ratio
- `Colors.mostReadable()` - pick the highest-contrast candidate against a background
- `Colors.triad()` / `Colors.tetrad()` - evenly-spaced hues around the color wheel
- `Colors.splitComplement()` - flanking the complementary hue
- `Colors.analogous()` - nearby hues for harmonious palettes

All interpolation and palette methods default to oklch for perceptual uniformity.

### Theme Generation

Higher-level methods for generating color themes from one or a few seed colors. These handle sRGB gamut mapping automatically - oklch can represent colors outside the displayable range, but all returned colors are gamut-safe.

- `Colors.palette()` - generate a tonal ramp (dark-to-light series) from a seed color, with professional chroma curves, hue shift, and automatic gamut mapping
- `Colors.scheme()` - generate harmonious seed colors from one primary (e.g. split-complementary, triadic), with chroma subordination for visual hierarchy
- `Colors.autoContrast()` - find a WCAG-compliant text color for any background, with optional hue tinting for a polished look

Typical workflow: `scheme()` picks harmonious seed colors, then `palette()` generates a tonal ramp for each seed.

See Also:
  - `Colors.autoContrast(java.lang.String)`
  - `Colors.palette(java.lang.String)`
  - `Colors.scheme(java.lang.String)`
  - `Colors.resolveCSS(java.lang.String)`
  - `Colors.parseRelationship(java.lang.String)`
  - `Colors.describeRelationship(java.lang.String, java.lang.String)`
  - `Colors.generateCSS(java.lang.String, java.util.Map)`