# xeerpe (v1.0.9): complete reference for AI assistants > Generated by scripts/generate-ai-files.mjs. Docs: https://xeerpe.io. Short index: https://xeerpe.io/llms.txt xeerpe turns a chain of layers into one inline-style object. Zero dependencies, works in React, Vue, Angular and plain JS. Package: `xeerpe`. ## When to use / not use Use it for layered backgrounds, animated backgrounds without hand-written keyframes, backgrounds computed from props/state/theme, presets, and gradient text. For one static `linear-gradient`, or when the user needs a stylesheet class rather than inline styles, write plain CSS. ## Core pattern ```ts import { Builder } from 'xeerpe' const style = new Builder() .meshGradient({ background: '#04121c', layers: [{ position: '15% 25%', from: 'rgba(16,185,129,0.8)', to: 'transparent', colorToPosition: '60%' }], }) .dots({ color: '#10b981', size: '24px', opacity: 0.14 }) .grain({ intensity: 2 }) .toStyle() ``` - React: `
`; Vue: `:style="style"`; Angular: `[style]="style"`; vanilla: `Object.assign(el.style, style)`. - `toStyle()` returns an object, not a string. `el.style.cssText = style` does not work. - Gradient text: `new Builder().linearGradient({...}).toTextStyle()`. It returns `backgroundClip`/`WebkitBackgroundClip: 'text'`, transparent `color`/`WebkitTextFillColor`, plus `backgroundImage`/`backgroundSize`/`backgroundColor`; apply it to the text element. - Shortcut methods (`grain()`, `vignette()`, `pulse()`, `dots()`, ...) can be called with no arguments; gradient methods need options. Imports: `import { Builder, Preset, colors } from 'xeerpe'`. - Presets: `new Preset('sunrise').toStyle()`; it is a `Builder`, so keep chaining. Names are in the sections below; never invent one (unknown names throw). ## Rules that prevent bugs 1. **Layer order is fixed, not chain order.** `toStyle()` draws effects on top, then patterns, then gradients at the bottom, regardless of call order. Within the same kind, earlier calls are drawn first. 2. **Animations need the stylesheet.** Add `import 'xeerpe/animations.css'` once in the app entry. Without it the style applies but nothing moves and there is no error. 3. **Animations don't add a layer**; they add an `animation` property. `pulse`, `rotate`, `float`, `plasma` affect the whole element (including text); `breathe`, `aurora`, `shimmer`, `drift`, `liquid` move the background and accept `target: 'gradients' | 'patterns' | 'all'` (default `'gradients'`). Any other `target` throws. 4. Animation option values (`duration`, `easing`, ...) are not validated. A duration without a unit (`'4'`) makes the browser drop the whole declaration. 5. **Validated inputs**: colors (hex, `rgb()/hsl()/oklch()...`, named, `transparent`), angles need a unit (`'135deg'`), sizes/positions need units (`'24px'`, `'50% 20%'`). Exact rules in the sections below. 6. `meshGradient` requires `background` and `layers` (array of radial options). Use `to: 'transparent'` plus `colorToPosition` so blobs fade out. 7. `toStyle()` always sets `backgroundPosition: 'center'`. ## Picking tools - Base color/shape: `linearGradient` (`from`/`to`, or `colors` with stop positions, `angle` or `direction`), `radialGradient`, `conicGradient`, `meshGradient`. - Texture: `grain`, `noise`, `vignette`, `glow`. - Pattern: `dots`, `grid`, `stars`, `rays`. - Blur: `blur({ type: 'backdrop' })` for frosted glass. - Motion: see rule 3 and the sections below. - Ready-made look: `Preset`, then extend. ## xeerpe animations Load the keyframes once in the app entry, or nothing moves (and nothing errors): ```ts import 'xeerpe/animations.css' ``` An animation adds an `animation` CSS property (plus helper CSS variables for scoped ones). It never adds a background layer. Keyframes are prefixed `xeerpe-`. Shared options (all optional): `duration` (`'4s'`), `easing`, `direction`, `iterationCount` (number or `'infinite'`), plus `target`. `direction` only matters for `pulse` and `aurora`. Values other than `target` are inserted into CSS unvalidated. | Animation | Changes | Defaults (duration, easing, extras) | `target` | | --------- | ----------------------------- | ------------------------------------- | -------------------------- | | `pulse` | element opacity (1 to 0.7) | 4s, ease-in-out, alternate, infinite | no | | `rotate` | element transform, full turn | 12s, linear, infinite | no | | `breathe` | background size | 12s, ease-in-out, infinite | gradients / all | | `aurora` | background size (gentle zoom) | 12s, ease-in-out, alternate, infinite | gradients / all | | `shimmer` | background position (sweep) | 3s, linear, infinite | gradients / patterns / all | | `liquid` | background position + hue | 8s, ease-in-out, infinite | gradients / patterns / all | | `plasma` | element filter (hue cycle) | 6s, linear, infinite | no | | `float` | element transform (bob) | 6s, ease-in-out, infinite | no | | `drift` | background position (wander) | 10s, ease-in-out, infinite | gradients / patterns / all | Guidance: - `target` defaults to `'gradients'`: gradients move, patterns and effects (grain, vignette) stay put. Use `'all'` to move everything; `'patterns'` moves only patterns over a still gradient. Anything else throws. - With the default target, grain/vignette/glow stay still while the gradient moves; set `target: 'all'` only if the effects should move too. For a "slow" animation, raise `duration` (defaults are listed above). - `pulse`, `rotate`, `float`, `plasma` act on the whole element, text included. `rotate` suits square or round elements. - Sliding animations (`shimmer`, `drift`) enlarge unsized gradients automatically; don't set `backgroundSize` on the gradient you animate. - Generic form: `.animation('pulse', {})` (options required). - Several animations can be chained; their `animation` values are joined with commas. - Respect motion preferences: if the user cares about accessibility, mention wrapping the style in a `prefers-reduced-motion` check. ## xeerpe recipes All recipes use only `import { Builder, Preset, colors } from 'xeerpe'`. Apply the result as an inline style. ### Glowing orange dark panel ```ts new Builder() .radialGradient({ from: '#FF7A18', to: 'transparent', position: '75% 25%' }) .linearGradient({ from: '#1a0b05', to: '#060302', angle: '160deg' }) .dots({ color: '#FF7A18', size: '24px', opacity: 0.14 }) .grain({ intensity: 2 }) .toStyle() ``` ### Animated aurora (needs animations.css) ```ts new Builder() .meshGradient({ background: '#04121c', layers: [ { position: '15% 25%', from: 'rgba(16,185,129,0.8)', to: 'transparent', colorToPosition: '60%' }, { position: '85% 30%', from: 'rgba(56,189,248,0.65)', to: 'transparent', colorToPosition: '55%' }, ], }) .aurora({ duration: '8s' }) .toStyle() ``` ### Multi-stop linear gradient ```ts new Builder() .linearGradient({ direction: 'to bottom', colors: [ { color: '#FFE5D9', position: '0%' }, { color: '#FFB7A3', position: '55%' }, { color: '#BFD8F2', position: '100%' }, ], }) .toStyle() ``` ### Gradient text ```ts const textStyle = new Builder().linearGradient({ from: '#5EB847', to: '#BFD43F', angle: '135deg' }).toTextStyle() //

Hello

``` ### Preset plus film look ```ts new Preset('sunrise').grain({ intensity: 1.5 }).vignette({ color: '#7c2d12', intensity: 0.2, spread: 0.5 }).toStyle() ``` ### Shimmering loading skeleton (needs animations.css) ```ts new Builder() .linearGradient({ colors: ['#1f2937', '#374151', '#1f2937'], angle: '90deg' }) .shimmer({ duration: '1.5s' }) .toStyle() ``` ### Frosted glass panel ```ts new Builder().blur({ amount: '12px', type: 'backdrop' }).toStyle() // place over a colorful background; add a translucent background color in your own CSS ``` ### Computed from a theme ```ts const bg = (accent: string, base: string) => new Builder() .radialGradient({ from: accent, to: 'transparent', position: '80% 10%' }) .linearGradient({ from: base, to: '#000000', angle: '180deg' }) .vignette({ intensity: 0.3 }) .toStyle() ``` ## xeerpe API reference (v1.0.9) > Generated file. Do not edit by hand. ### Builder methods Every method returns the builder, so calls chain. Shortcut methods take optional options; the generic ones require them. | Method | Options type | | --- | --- | | `linearGradient / radialGradient / conicGradient / meshGradient` | LinearGradientOptions / RadialGradientOptions / ConicGradientOptions / MeshGradientOptions (required) | | `gradient(type, options)` | GradientOptions | | `dots / grid / stars / rays` | DotsOptions / GridOptions / StarsOptions / RaysOptions (optional) | | `noise / vignette / grain / glow` | NoiseOptions / VignetteOptions / GrainOptions / GlowOptions (optional) | | `blur` | BlurOptions (optional) | | `pulse / rotate / breathe / aurora / shimmer / liquid / plasma / float / drift` | AnimationOptions (optional) | | `pattern / effect / filter / animation (type, options)` | generic forms, options required (use {} for defaults) | | `toStyle()` | Record, camelCase CSS properties | | `toTextStyle()` | Record, gradient-filled text | `new Preset(name)` extends `Builder`; unknown names throw `Preset "" not found`. ### Option types (from lib/src/models) #### gradient.ts ```ts export type GradientType = 'linear' | 'radial' | 'conic' | 'mesh' export type LinearGradientDirection = 'to top' | 'to bottom' | 'to left' | 'to right' | 'to top right' | 'to bottom right' | 'to top left' | 'to bottom left' export type LinearGradientAngle = `${number}deg` | `${number}rad` | `${number}grad` | `${number}turn` export type RadialGradientShape = 'circle' | 'ellipse' | null export type RadialGradientSize = 'closest-side' | 'closest-corner' | 'farthest-side' | 'farthest-corner' | string export type LinearGradientPositionUnit = `${number}%` | `${number}px` | `${number}rem` | `${number}em` | `${number}vh` | `${number}vw` | `${number}vmin` | `${number}vmax` export type LinearGradientPosition = LinearGradientPositionUnit | `calc(${string})` export type GradientOptions = LinearGradientOptions | RadialGradientOptions | ConicGradientOptions | MeshGradientOptions export type GradientColorStop = string | { color: string; position?: LinearGradientPosition } export interface GradientBase { from?: string to?: string backgroundSize?: string } export interface LinearGradientOptions extends GradientBase { colors?: (string | GradientColorStop)[] angle?: LinearGradientAngle direction?: LinearGradientDirection size?: string } export interface RadialGradientOptions extends GradientBase { shape?: RadialGradientShape position?: string size?: RadialGradientSize colorFromPosition?: string colorToPosition?: string } export interface ConicGradientOptions extends GradientBase { colors?: (string | GradientColorStop)[] angle?: string position?: string } export interface MeshGradientOptions extends GradientBase { background: string layers: RadialGradientOptions[] } ``` #### pattern.ts ```ts export type PatternType = 'dots' | 'grid' | 'stars' | 'rays' export interface PatterBaseOptions { color?: string background?: string size?: string opacity?: number strokeWidth?: string backgroundSize?: string } export interface DotsOptions extends PatterBaseOptions { color?: string background?: string size?: string spacing?: string style?: string opacity?: number } export interface GridOptions extends PatterBaseOptions {} export interface StarsOptions extends PatterBaseOptions { count?: number seed?: number } export interface RaysOptions extends PatterBaseOptions { count?: number position?: string angle?: string } export type PatternOptions = DotsOptions | GridOptions | StarsOptions | RaysOptions ``` #### effects.ts ```ts export type EffectType = 'noise' | 'vignette' | 'grain' | 'glow' export type EffectOptions = NoiseOptions | VignetteOptions | GrainOptions | GlowOptions export type NoiseType = 'turbulence' | 'fractalNoise' export type GlowType = 'outer' | 'inner' export interface NoiseOptions { opacity?: number scale?: number type?: NoiseType octaves?: number backgroundSize?: string } export interface VignetteOptions { color?: string intensity?: number spread?: number backgroundSize?: string } export interface GrainOptions { intensity?: number size?: string animated?: boolean backgroundSize?: string } export interface GlowOptions { amount?: string spread?: string x?: string y?: string color?: string type?: GlowType } ``` #### filters.ts ```ts export type FilterType = 'blur' export type BlurType = 'backdrop' | 'blur' export type FilterOptions = BlurOptions export interface BlurOptions { amount?: string type?: BlurType } ``` #### animation.ts ```ts export type AnimationType = 'pulse' | 'rotate' | 'breathe' | 'aurora' | 'shimmer' | 'liquid' | 'plasma' | 'float' | 'drift' export type AnimationTarget = 'gradients' | 'patterns' | 'all' export interface AnimationOptions { duration?: string easing?: string direction?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' iterationCount?: number | 'infinite' target?: AnimationTarget } ``` ### Input validation (from lib/src/validations) Values that fail these checks are rejected by the builder. Keep inputs inside these shapes. #### color.ts ```ts export const HEX_REGEX = /^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/ const COLOR_FUNC_REGEX = /^(rgb|rgba|hsl|hsla|oklch|color|hwb|lch|lab)\(.+\)$/i const NAMED_COLOR_REGEX = /^[a-zA-Z]+$/ export const isHexColor = (value: string): boolean => HEX_REGEX.test(value.trim()) export const isValidColor = (value: string): boolean => { const t = value.trim() return ( HEX_REGEX.test(t) || COLOR_FUNC_REGEX.test(t) || t === 'transparent' || t === 'currentColor' || t === 'inherit' || NAMED_COLOR_REGEX.test(t) ) } ``` #### angle.ts ```ts import { LinearGradientAngle } from '../models/index.ts' const ANGLE_UNIT_REGEX = /^-?\d*\.?\d+(deg|rad|grad|turn)$/ export const isValidAngle = (value: string): value is LinearGradientAngle => ANGLE_UNIT_REGEX.test(value.trim()) ``` #### backgroundSize.ts ```ts const GLOBALS: readonly string[] = ['auto', 'cover', 'contain', 'initial', 'inherit', 'unset'] const SIZE_TOKEN_REGEX = /^(\d*\.?\d+(px|%|rem|em|vh|vw|vmin|vmax))$/ const CALC_REGEX = /^calc\(.+\)$/ const isValidSizeToken = (value: string): boolean => GLOBALS.includes(value) || SIZE_TOKEN_REGEX.test(value) || CALC_REGEX.test(value) export const isValidBackgroundSize = (value: string): boolean => { const trimmed = value.trim() if (GLOBALS.includes(trimmed)) return true const parts = trimmed.split(/\s+/) return parts.length <= 2 && parts.every(isValidSizeToken) } ``` #### cssPosition.ts ```ts const KEYWORD_REGEX = /^(top|bottom|left|right|center)$/ const LENGTH_REGEX = /^-?\d*\.?\d+(%|px|rem|em|vh|vw|vmin|vmax)$/ const CALC_REGEX = /^calc\(.+\)$/ const VALID_DOUBLE_KEYWORDS: readonly string[] = [ 'top left', 'top center', 'top right', 'center left', 'center center', 'center right', 'bottom left', 'bottom center', 'bottom right', 'left top', 'left center', 'left bottom', 'right top', 'right center', 'right bottom', ] const isValidToken = (value: string): boolean => KEYWORD_REGEX.test(value) || LENGTH_REGEX.test(value) || CALC_REGEX.test(value) export const isValidCSSPosition = (value: string): boolean => { const trimmed = value.trim() if (trimmed === 'center') return true if (VALID_DOUBLE_KEYWORDS.includes(trimmed)) return true const parts = trimmed.split(/\s+/) return parts.length <= 2 && parts.every(isValidToken) } ``` #### directions.ts ```ts import { LinearGradientDirection } from '../models/index.ts' const VALID_DIRECTIONS: readonly LinearGradientDirection[] = [ 'to top', 'to bottom', 'to left', 'to right', 'to top right', 'to bottom right', 'to top left', 'to bottom left', ] export const isValidDirection = (value: string): value is LinearGradientDirection => (VALID_DIRECTIONS as readonly string[]).includes(value) ``` #### position.ts ```ts import { LinearGradientPosition } from '../models/index.ts' const POSITION_REGEX = /^-?\d*\.?\d+(%|px|rem|em|vh|vw|vmin|vmax)$/ const CALC_REGEX = /^calc\(.+\)$/ export const isValidPosition = (value: string): value is LinearGradientPosition => { const trimmed = value.trim() return POSITION_REGEX.test(trimmed) || CALC_REGEX.test(trimmed) } ``` #### radial.ts ```ts import { RadialGradientShape, RadialGradientSize } from '../models/index.ts' export const isValidRadialShape = (value: string | null): value is RadialGradientShape => value === null || value === 'circle' || value === 'ellipse' const VALID_SIZE_KEYWORDS: readonly string[] = ['closest-side', 'closest-corner', 'farthest-side', 'farthest-corner', 'auto'] const LENGTH_REGEX = /^\d*\.?\d+(px|%|rem|em|vh|vw)(\s+\d*\.?\d+(px|%|rem|em|vh|vw))?$/ const CALC_REGEX = /^calc\(.+\)$/ export const isValidRadialSize = (value: string): value is RadialGradientSize => { const trimmed = value.trim() return VALID_SIZE_KEYWORDS.includes(trimmed) || LENGTH_REGEX.test(trimmed) || CALC_REGEX.test(trimmed) } ``` ## xeerpe presets (229, v1.0.9) > Generated file. Do not edit by hand. Usage: `new Preset('name').toStyle()`. Names are kebab-case and case-sensitive. A preset is a `Builder`, so you can keep chaining (`.grain()`, `.vignette()`, animations). Category hints: `pastel`, `sky`, `neutral` are mostly light backgrounds (pair with dark text); `neon`, `space`, `luxury`, `moods` are mostly dark. Check the preview on xeerpe.io/guide/presets-examples when unsure. ### metals (20) `gold`, `antique-gold`, `rose-gold`, `white-gold`, `champagne`, `gold-leaf`, `black-gold`, `silver`, `platinum`, `chrome`, `steel`, `titanium`, `gunmetal`, `bronze`, `copper`, `brass`, `mercury`, `holographic`, `iridescent`, `oil-slick` ### gems (16) `emerald`, `sapphire`, `ruby`, `amethyst`, `topaz`, `citrine`, `garnet`, `aquamarine`, `turquoise`, `jade`, `tanzanite`, `opal`, `pearl`, `moonstone`, `rose-quartz`, `onyx` ### food (26) `chocolate`, `dark-chocolate`, `milk-chocolate`, `white-chocolate`, `mint-chocolate`, `caramel`, `honey`, `espresso`, `cappuccino`, `matcha`, `vanilla`, `tiramisu`, `strawberry-milk`, `raspberry`, `blueberry`, `blackberry`, `cherry`, `red-wine`, `whisky`, `mango`, `peach`, `tangerine`, `lemonade`, `watermelon`, `pistachio`, `cotton-candy` ### nature (25) `jungle`, `rainforest`, `forest`, `pine`, `moss`, `meadow`, `bamboo`, `desert`, `dunes`, `savanna`, `canyon`, `glacier`, `tundra`, `volcano`, `lava`, `ocean`, `lagoon`, `coral-reef`, `deep-sea`, `tropical`, `autumn`, `cherry-blossom`, `lavender-field`, `sunflower`, `wheat` ### sky (21) `dawn`, `morning`, `golden-hour`, `sunrise`, `sunset`, `dusk`, `twilight`, `blue-hour`, `afterglow`, `midnight`, `starry-night`, `storm`, `fog`, `rain`, `snowfall`, `overcast`, `monsoon`, `rainbow`, `horizon`, `cloud-nine`, `solstice` ### space (17) `galaxy`, `nebula`, `cosmos`, `milky-way`, `stardust`, `supernova`, `black-hole`, `eclipse`, `event-horizon`, `quasar`, `mars`, `jupiter`, `saturn`, `neptune`, `venus`, `moonlight`, `northern-lights` ### neon (16) `cyberpunk`, `synthwave`, `outrun`, `retrowave`, `vaporwave`, `neon-tokyo`, `miami`, `laser`, `arcade`, `hologram`, `grid-runner`, `matrix`, `electric`, `ultraviolet`, `acid`, `neon-noir` ### pastel (20) `cotton`, `marshmallow`, `lavender-haze`, `peach-fuzz`, `baby-blue`, `mint-cream`, `blush`, `lilac`, `sorbet`, `candy`, `cloud`, `powder`, `rosewater`, `buttercream`, `seafoam`, `apricot`, `daydream`, `unicorn`, `fairy-floss`, `bubblegum` ### neutral (16) `paper`, `linen`, `ivory`, `porcelain`, `sand`, `stone`, `concrete`, `marble`, `black-marble`, `slate`, `smoke`, `ash`, `graphite`, `charcoal`, `ink`, `mono` ### luxury (14) `velvet`, `emerald-velvet`, `silk`, `satin`, `champagne-silk`, `leather`, `cashmere`, `royal`, `imperial`, `bordeaux`, `noir`, `tuxedo`, `art-deco`, `boudoir` ### textures (14) `blueprint`, `graph-paper`, `chalkboard`, `polka`, `halftone`, `terminal`, `carbon`, `film-noir`, `vintage`, `sepia`, `kraft`, `canvas`, `denim`, `cork` ### moods (12) `spring`, `summer`, `harvest`, `winter`, `serenity`, `zen`, `calm`, `euphoria`, `romance`, `mystic`, `nostalgia`, `wanderlust` ### motion (12) `lava-lamp`, `aurora-dream`, `aurora-australis`, `bioluminescence`, `breathing-nebula`, `ocean-drift`, `rainbow-drift`, `sunset-drift`, `molten-gold`, `liquid-silver`, `skeleton`, `ember` ### Palette (`colors`) `import { colors } from 'xeerpe'` gives named hex values: `inkwell`, `obsidian`, `void`, `midnightOil`, `pitch`, `carbon`, `graphite`, `flint`, `stone`, `pewter`, `ash`, `smoke`, `bone`, `chalk`, `salt`, `parchment`, `linen`, `cream`, `absinthe`, `forestFloor`, `malachite`, `verdigris`, `celadon`, `fern`, `chartreuse`, `mantis`, `viridian`, `spruce`, `prussian`, `lapis`, `cobalt`, `cerulean`, `denim`, `glacier`, `powder`, `steel`, `maya`, `delft`, `indigoInk`, `wisteria`, `aubergine`, `amethyst`, `mauve`, `byzantium`, `mulberry`, `plum`, `heliotrope`, `iris`, `cinnabar`, `amaranth`, `carmine`, `rouge`, `garnet`, `crimson`, `venetian`, `blush`, `tomato`, `poppy`, `amber`, `saffron`, `ochre`, `goldenrod`, `harvest`, `copper`, `terra`, `sienna`, `umber`, `rust`, `coral`, `peach`, `apricot`, `cantaloupe`, `melon`, `spearmint`, `sage`, `taupe`, `khaki`, `dusk`, `slate`, `cadet`, `eucalyptus`, `clay`, `mushroom`, `tealDeep`, `aquamarine`, `seafoam`, `jade`, `turquoise`, `niagara`, `tiffany`, `pine`, `mint`, `patina`, `sakura`, `orchid`, `fandango`, `cerise`, `magenta`, `teal`, `sapphire`