asciify-engine 4.18.0 → 4.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asciify-engine",
3
- "version": "4.18.0",
3
+ "version": "4.19.0",
4
4
  "description": "Framework-agnostic ASCII art engine. Convert images, videos, and GIFs into ASCII art rendered on canvas, or run full-bleed GPU character fields with a fluid cursor wake.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -2,13 +2,13 @@
2
2
  name: asciify-engine
3
3
  description: Apply Asciify the way asciify.org does - ASCII components and backgrounds that belong in a real interface, inked from the theme, clear around text, inside the page's radii and motion. Use for UI components in characters (loading, status, toasts, tabs, AI states, charts, transitions, pages), animated ASCII backgrounds, and also photo, video and GIF conversion, GPU character fields, artwork looks for wallpapers, posters and prints, art styles and export, hover and motion, layered typography and rendering performance.
4
4
  metadata:
5
- tested-engine: "4.18.0"
5
+ tested-engine: "4.19.0"
6
6
  updated: "2026-10-17"
7
7
  ---
8
8
 
9
9
  # Asciify Engine
10
10
 
11
- Use the published `asciify-engine` npm package. Tested against **4.18.0**. Check the application's installed version and its public types before using newer options; a local checkout can contain unpublished changes.
11
+ Use the published `asciify-engine` npm package. Tested against **4.19.0**. Check the application's installed version and its public types before using newer options; a local checkout can contain unpublished changes.
12
12
 
13
13
  - Agent entry: https://asciify.org/skill (redirects to this Markdown document).
14
14
  - Components: https://asciify.org/components · Looks: https://asciify.org/looks · Backgrounds: https://asciify.org/backgrounds
@@ -36,7 +36,7 @@ Most requests are a feeling ("make the loading state feel alive", "a calm backgr
36
36
  | The user wants | Use |
37
37
  | --- | --- |
38
38
  | A UI component in characters: button loading, status, toasts, tabs, pills, odometer, chart, AI thinking and streaming, transitions, sign-in, pricing, 404 | `asciify-engine/kit` ([applying-asciify.md](references/applying-asciify.md), [components.md](references/components.md), [kit.md](references/kit.md)) |
39
- | A background behind a hero, pricing, docs or a section, light or dark | Kit `fieldBackground(el, { preset: 'hero', clear })` (asciify.org's hero) or `background(el, { preset, clear })` with one of the 26 presets below |
39
+ | A background behind a hero, pricing, docs or a section, light or dark | Kit `fieldBackground(el, { preset: 'hero', clear })` (asciify.org's hero) or `background(el, { preset, clear })` with one of the 13 curated presets below |
40
40
  | Their word or brand in characters | Kit `wordmark`, or `background()` with `wordField` |
41
41
  | Their video in characters on the page | Kit `asciiVideo` |
42
42
  | Their photo, video or GIF converted, optionally answering the cursor | Advanced: `asciify` / `asciifyVideo` / `asciifyGif`, plus `mountHover` from `/hover` |
@@ -57,25 +57,22 @@ const b = beam(card, { palette: 'mono', mode: 'pulse' });
57
57
  // On unmount: b.destroy();
58
58
  ```
59
59
 
60
- `background()`, the 26 presets, `lazy`, `poster`, `setFieldBudget` and `setGlobalLook` are new in 4.14.0. Check that the installed `asciify-engine/kit` exports them; if not, upgrade ([upgrading.md](references/upgrading.md)).
60
+ `background()`, its presets, `lazy`, `poster`, `setFieldBudget` and `setGlobalLook` are new in 4.14.0; `halo`, `ripple`, `mesh`, `interference`, `constellation`, `cascade`, the GPU `caustics`, `contour` and `aurora`, and the `mark` option are new in 4.19.0. Check that the installed `asciify-engine/kit` exports them; if not, upgrade ([upgrading.md](references/upgrading.md)).
61
61
 
62
62
  ## Backgrounds
63
63
 
64
- `background(element, { preset })` draws every background on asciify.org/backgrounds with the site's own renderers and graphite inks. Import presets by name; a page pays only for those it imports. Which one suits which surface, and how to keep it calm, is in [applying-asciify.md](references/applying-asciify.md#9-backgrounds).
64
+ `background(element, { preset })` draws every background on asciify.org/backgrounds as a scene of the GPU glyph field, in the site's graphite inks and following the global look. Import presets by name; a page pays only for those it imports. `cursor: false` turns the pointer response off for any of them. Which one suits which surface, and how to keep it calm, is in [applying-asciify.md](references/applying-asciify.md#9-backgrounds).
65
65
 
66
66
  ```ts
67
- import { background, halftone } from 'asciify-engine/kit';
68
- const bg = background(pricing, { preset: halftone, clear: pricingCopy });
67
+ import { background, swell } from 'asciify-engine/kit';
68
+ const bg = background(pricing, { preset: swell, clear: pricingCopy });
69
69
  ```
70
70
 
71
- The 26 presets, as export → `id` (name):
71
+ The 13 curated presets, as export → `id` (name), all on the GPU glyph field (WebGL2, sharing the context budget): `swell` (Swell, dots or characters), `drift` (Drift), `halo` (Halo), `caustics` (Caustics), `contour` (Contour), `aurora` (Aurora), `ripple` (Ripple), `mesh` (Mesh), `interference` (Interference), `constellation` (Constellation), `cascade` (Cascade), `wordField` → `field` (Field), `fluid` (Fluid).
72
72
 
73
- - GPU glyph field (WebGL2, shares the context budget): `drift` → `drift` (Drift), `halftone` → `halftone` (Halftone), `swell` → `swell` (Swell), `wordField` → `field` (Field), `fluid` → `fluid` (Fluid).
74
- - 2D canvas (no WebGL): `caustics` → `caustics` (Caustics), `contour` → `contour` (Contour), `facet` → `facet` (Facet), `etch` → `etch` (Etch), `moire` → `moire` (Moiré), `weave` → `weave` (Weave), `veil` → `veil` (Veil), `dune` → `dune` (Dune), `wave` → `wave` (Wave), `aurora` → `aurora` (Aurora), `noise` → `noise` (Noise), `silk` → `silk` (Silk), `rain` → `rain` (Rain), `stars` → `stars` (Stars), `pulse` → `pulse` (Pulse), `grid` → `grid` (Grid), `voidWell` → `void` (Void), `morph` → `morph` (Morph), `fire` → `fire` (Fire), `dna` → `dna` (DNA), `terrain` → `terrain` (Terrain), `circuit` → `circuit` (Circuit).
73
+ The retired presets (`halftone`, `dna`, `circuit`, `fire`, `grid`, `morph`, `noise`, `pulse`, `rain`, `silk`, `stars`, `terrain`, `veil`, `voidWell`, `wave`, `weave`, `dune`, `etch`, `facet`, `moire`) are still exported and marked `@deprecated` so old code runs; do not reach for them in new work. [kit.md](references/kit.md#backgrounds) maps each to its replacement. `fieldBackground` is separate: its `hero`, `brand` and `notFound` presets are the asciify.org hero ground, the same ground in the brand colour, and the 404.
75
74
 
76
- `voidWell` is the export for the `void` preset, because `void` is reserved in JavaScript. `wordField`'s id is `field`, the name the site uses. `fieldBackground` is separate: its `hero`, `brand` and `notFound` presets are the asciify.org hero ground, the same ground in the brand colour, and the 404.
77
-
78
- Downloaded templates from asciify.org/backgrounds (`asciiBackground` from a local `./wave.js`) still work in apps that already use them; new work uses `background()`.
75
+ Templates already downloaded from asciify.org/backgrounds (`asciiBackground` from a local `./wave.js`) keep working in apps that ship them, but the site no longer offers them; move those apps to `background()` with the closest preset (kit.md maps each).
79
76
 
80
77
  ## Install the agent skill
81
78
 
@@ -57,9 +57,9 @@ Rules:
57
57
  - **Never a new colour.** No hex that is not a token (map to the app's tokens as above), no black canvas on a light page, no white glow on a coloured image.
58
58
 
59
59
  ```ts
60
- import { background, halftone, statusOrb, beam } from 'asciify-engine/kit';
60
+ import { background, swell, statusOrb, beam } from 'asciify-engine/kit';
61
61
 
62
- background(pricing, { preset: halftone, clear: pricingCopy, ink: '--ascii-ink' }); // the token, re-read per theme
62
+ background(pricing, { preset: swell, clear: pricingCopy, ink: '--ascii-ink' }); // the token, re-read per theme
63
63
  const orb = statusOrb(orbSlot); // strong ink at rest; outcomes read --ascii-success, --ascii-warning, --ascii-error
64
64
  beam(planCard, { palette: 'mono', mode: 'pulse' }); // the quiet beam; 'colorful' only when asked for
65
65
  orb.loading();
@@ -93,8 +93,8 @@ Text never sits on raw characters, and never in a box. Two layers do the work:
93
93
 
94
94
  | Surface | Cell size | Characters | Site reference |
95
95
  | --- | --- | --- | --- |
96
- | Page hero ground | 10–12px, broad shapes | Sparse: `' .:+*#'` in the mono face | `fieldBackground` `hero` (10px), `drift` (11px), `halftone` (14px dot spacing), `swell` (10px dot spacing) |
97
- | Section band or card stage | 7–10px | Fuller ramp for images (`' .:-=+*#%@'`), quiet ramp for grounds | images 7px, character fields 10px, halftone 9px |
96
+ | Page hero ground | 10–12px, broad shapes | Sparse: `' .:+*#'` in the mono face | `fieldBackground` `hero` (10px), `drift` (11px), `swell` (10px dot spacing), the scene presets (11px) |
97
+ | Section band or card stage | 7–10px | Fuller ramp for images (`' .:-=+*#%@'`), quiet ramp for grounds | images 7px, character fields 10px, dots 9px |
98
98
  | Control: button, pill, tabs, code input, odometer | Leave it to the kit | The kit fits cells to the element's text | Use a monospaced label for `buttonLoading` |
99
99
 
100
100
  - One density per surface: a stage does not mix a 7px image and a 12px ground.
@@ -187,29 +187,27 @@ publishButton.addEventListener('click', async () => {
187
187
 
188
188
  ## 9. Backgrounds
189
189
 
190
- `background(element, { preset })` draws any of the 26 presets from asciify.org/backgrounds under the element's content. Choose by surface:
190
+ `background(element, { preset })` draws any of the 13 curated presets from asciify.org/backgrounds under the element's content. Choose by surface:
191
191
 
192
192
  | Surface | Presets | Notes |
193
193
  | --- | --- | --- |
194
- | Product hero, pricing, docs landing, behind copy | `drift`, `halftone`, `swell`, or `fieldBackground` `hero` | GPU grounds that clear around `clear`. `halftone` is the calmest; `swell` is the finest, a dot grid in slow waves that stays quiet in the middle even without `clear`; `fieldBackground` `hero` is asciify.org's own hero, with ripples and `pulse()`. |
194
+ | Product hero, pricing, docs landing, behind copy | `swell`, `drift`, `halo`, or `fieldBackground` `hero` | Grounds that clear around `clear`. `swell` is the finest, a grid in slow waves (dots, or characters with `mark: 'glyph'`) quiet in the middle even without `clear`; `halo` frames a single headline; `fieldBackground` `hero` is asciify.org's own hero, with ripples and `pulse()`. |
195
195
  | A brand or name moment | `wordField` (id `field`), `fieldBackground` `brand` | Your word in the field; keep copy off its centre. |
196
- | Art-first hero with little copy | `fluid` | The original Asciify hero, 7px cells at 0.7 opacity. Not behind reading text. |
197
- | Quiet texture: section bands, footers, empty states, side panels | `caustics`, `contour`, `facet`, `etch`, `moire`, `weave`, `veil`, `dune`, `silk` | Canvas, no cursor, slow. The safest behind text after `halftone`. |
198
- | An interactive moment the visitor plays with | `wave`, `aurora`, `noise`, `stars`, `pulse`, `voidWell` | They answer the cursor. Keep them away from forms and body copy. |
199
- | A themed subject the page is about | `rain`, `grid`, `morph`, `fire`, `dna`, `terrain`, `circuit` | Loud. Use only when the subject matches (DNA for a biotech page), with low opacity and copy beside, not over. |
196
+ | Art-first hero with little copy | `fluid`, `mesh` | `fluid` is the original Asciify hero, 7px cells at 0.7 opacity; `mesh` is a soft gradient in characters. Not behind reading text. |
197
+ | Quiet texture: section bands, footers, empty states, side panels | `caustics`, `contour`, `interference`, `constellation` | Fine lines, slow. Safe behind text with `clear`. |
198
+ | An ambient or interactive moment | `aurora`, `ripple`, `cascade` | `aurora` sits above the copy; `ripple` drops rings where the pointer moves; `cascade` falls in three depths. Keep them away from forms and body copy. |
200
199
 
201
200
  Keep them calm:
202
201
 
203
202
  - `speed` at or below the preset's default; `cursor: false` near forms and copy.
204
- - On canvas presets behind text, `opacity` 0.5–0.8; GPU grounds already draw quietly.
205
- - Always `clear` the copy and add the veil from section 3; on the /backgrounds page the copy also sits on the side the field fades toward.
203
+ - Every preset keeps a quiet zone; still `clear` the copy and add the veil from section 3.
206
204
  - One background per page section, under one `isolation: isolate` host with its own background colour.
207
205
  - `setPreset()` cross-fades in place for a picker; do not mount a second background.
208
206
 
209
207
  ```ts
210
208
  import { background, contour, caustics } from 'asciify-engine/kit';
211
209
 
212
- const section = background(features, { preset: contour, clear: featuresCopy, opacity: 0.6, cursor: false });
210
+ const section = background(features, { preset: contour, clear: featuresCopy, opacity: 0.8, cursor: false });
213
211
  themePicker.addEventListener('change', () => section.setPreset(caustics)); // keeps clear, opacity and cursor
214
212
  ```
215
213
 
@@ -482,16 +482,16 @@ playButton.onclick = () => playButton.setAttribute('aria-label', v.toggle() ? 'P
482
482
  Category: Backgrounds
483
483
 
484
484
  Prompt:
485
- “Put the Asciify Swell background behind our hero: a fine dot grid that swells in slow rolling waves, quiet in the middle. Keep it clear around the headline and let it answer the cursor.”
485
+ “Put the Asciify Swell background behind our hero: a fine grid that swells in slow rolling waves, quiet in the middle. Dots by default, or characters. Keep it clear around the headline and let it answer the cursor.”
486
486
 
487
487
  ```ts
488
488
  import { background, swell } from 'asciify-engine/kit';
489
489
 
490
- // One of 27 presets. Import only the one you use; bg.setPreset(other) cross-fades to another.
490
+ // One of 13 presets. Import only the one you use; bg.setPreset(other) cross-fades to another.
491
491
  const bg = background(heroSection, { preset: swell, clear: heroText });
492
492
  ```
493
493
 
494
- Any preset from [the kit reference](kit.md#backgrounds) fits the same call: `swell`, `drift`, `halftone`, `wordField` and `fluid` run on the GPU glyph field; the rest are 2D canvases. For asciify.org's own hero ground, with the frosted veil and `pulse()`, use `fieldBackground(heroSection, { preset: 'hero', clear: heroText })`.
494
+ Any preset from [the kit reference](kit.md#backgrounds) fits the same call: `swell`, `drift`, `halo`, `caustics`, `contour`, `aurora`, `ripple`, `mesh`, `interference`, `constellation`, `cascade`, `wordField` and `fluid`, all on the GPU glyph field. `cursor: false` turns the pointer response off; `swell` takes `mark: 'glyph'` or a `charset` for characters instead of dots. For asciify.org's own hero ground, with the frosted veil and `pulse()`, use `fieldBackground(heroSection, { preset: 'hero', clear: heroText })`.
495
495
 
496
496
  ## Advanced: raw field
497
497
 
@@ -39,7 +39,7 @@ For an interface component or a background, use `asciify-engine/kit` and follow
39
39
  | --- | --- | --- |
40
40
  | A photo, video or GIF converted on their page, with optional hover | `asciify`, `asciifyVideo`, `asciifyGif` (+ `mountHover` from `/hover`) | Lightest path. Disable core hover and motion when `/hover` owns them. |
41
41
  | A full-bleed hero or brand field that must feel smooth under the cursor, their name or word as the characters, an Unseen-style look | `mountGlyphField` from `/field` | WebGL2 on a GPU, 120 fps class. Glyph ramps only. Keep a poster and a fallback. See [glyph-field.md](glyph-field.md). |
42
- | A calm background for a product page, docs, pricing or SaaS hero, in light or dark | Kit `background(el, { preset: halftone, clear })` or `fieldBackground(el, { preset: 'hero', clear })` | Graphite ink, clear zone plus veil. See [applying-asciify.md](applying-asciify.md#9-backgrounds). Raw `mountGlyphField` with `mark: 'dot'` only for a look the kit lacks ([glyph-field.md](glyph-field.md#halftone-for-interfaces-412)). |
42
+ | A calm background for a product page, docs, pricing or SaaS hero, in light or dark | Kit `background(el, { preset: swell, clear })` or `fieldBackground(el, { preset: 'hero', clear })` | Graphite ink, clear zone plus veil. See [applying-asciify.md](applying-asciify.md#9-backgrounds). Raw `mountGlyphField` with `mark: 'dot'` only for a look the kit lacks ([glyph-field.md](glyph-field.md#halftone-for-interfaces-412)). |
43
43
  | Art styles (halftone, dither, braille, print, mosaic, LED…), saved looks, backdrops, masks, effects, PNG/MP4/GIF export | `mountStudio` from `/studio` | Studio owns motion, hover and finish. Start from `studioLook(id)` when one of the 12 looks matches the mood. |
44
44
  | Several media and text layers in one artwork | `mountStudioProject` from `/studio` | One loop and budget for up to eight layers. See [layered-projects.md](layered-projects.md). |
45
45
  | An ambient animated background with no media (rain, stars, waves, aurora…) | Kit `background(el, { preset })` with one of the 26 presets | Import presets by name from `asciify-engine/kit`. See [applying-asciify.md](applying-asciify.md#9-backgrounds) for which suits which surface. |
@@ -34,7 +34,7 @@ Size the canvas with CSS (for example `position:absolute; inset:0; width:100%; h
34
34
  | Option | Default | Notes |
35
35
  | --- | --- | --- |
36
36
  | `source` | none | URL (`.mp4`, `.webm`, `.mov` load as muted, looping, inline video), `HTMLImageElement`, `HTMLVideoElement`, `HTMLCanvasElement` or `ImageBitmap`. Cross-origin media needs CORS. |
37
- | `scene` | `'flow'` | Generated motion when there is no source: `'flow'` (domain-warped noise), `'drift'` (a few broad lobes, made for halftone, 4.12), `'swell'` (three crossing sine swells rolling diagonally, made for a fine dot grid), `'orb'` (lit sphere) or `'none'` (blank, wake only). |
37
+ | `scene` | `'flow'` | Generated motion when there is no source: `'flow'` (domain-warped noise), `'drift'` (a few broad lobes, made for halftone, 4.12), `'swell'` (three crossing sine swells rolling diagonally, made for a fine dot grid), `'orb'` (lit sphere), the kit's background scenes `'caustics'`, `'contour'`, `'aurora'`, `'ripple'`, `'halo'`, `'interference'`, `'mesh'`, `'cascade'` and `'constellation'` (`FIELD_SCENES` lists them all), or `'none'` (blank, wake only). |
38
38
  | `mark`, `dotScale` | `'glyph'`, `0.9` | `'dot'` draws a halftone: one circle per cell whose area follows tone, antialiased at any pixel ratio. `dotScale` is the largest dot as a fraction of the cell; about 0.6 keeps a calm, open grid. (4.12) |
39
39
  | `mark` (Studio styles) | | `FIELD_MARKS` also holds the Studio's tile and print styles, drawn per cell in the composite pass from the cell's tone and colour (one shader branch each, no extra pass or texture). Tiles, which fade with tone in `color: 'ink'` and stay solid in `'source'`: `'pixel'` (filled cell), `'mosaic'` (gapped tile), `'lego'` (gapped brick lit from above, with a ringed stud), `'voxel'` (isometric cube, faces at 1, 0.72 and 0.42), `'disco'` (gapped tile, lit upper facet, shaded lower), `'hex'` (flat-topped hexagon), `'led'` (round lamp, soft halo, glint). `'dither'` lights a 4x4 Bayer screen of about five dots a cell. `'cmyk'` separates the cell's hue into offset cyan, magenta and yellow dots, with the neutral share as a key dot in the ink's own lightness. Print marks, whose size carries the tone: `'stipple'` (four jittered dots a cell), `'engraving'` (parallel cuts at -35°, running on across cells), `'crosshatch'` (two more directions join in darker tones), `'woodblock'` (broad carved bands in five steps, edges wavering), `'risograph'` (main ink and a coral second ink, offset), `'pointillism'` (four small strokes, their shade varied). Every mark but `'dot'` leaves blank the cells the `charset` leaves blank (its first glyph), so keep a ramp that starts with a space. Cells near square suit them best. |
40
40
  | `scale` | `1` | Feature size of generated scenes; higher is finer. Use about 1.8 on phones, where the field is tall. (4.12) |
@@ -190,7 +190,7 @@ const off = subscribeGlobalLook(look => menu.value = look?.charset ?? '');
190
190
  orb.update({ ink: '--brand', look: { cellSize: 6 } });
191
191
  ```
192
192
 
193
- `setGlobalLook({ style })` takes one of the Studio's 24 render styles (`KIT_STYLES`, typed `KitStyle`, in `STUDIO_STYLES` order). Glyph-like styles (`ascii`, `blocks`, `braille`, `lines`, `cross`, `diagonal`, `diamond`, `mixed`) bring their ramp, which a `charset` beside them overrides; `dots` is the halftone mark; the rest (`pixel`, `mosaic`, `lego`, `voxel`, `disco`, `dither`, `hex`, `led`, `cmyk`, `stipple`, `engraving`, `crosshatch`, `woodblock`, `risograph`, `pointillism`) switch the field's `mark` and keep each field's own charset, which decides the cells left blank. Unknown styles and empty charsets are dropped. `setGlobalLook(null)` gives each field its own mark and characters back.
193
+ `setGlobalLook({ style })` takes one of the Studio's 24 render styles (`KIT_STYLES`, typed `KitStyle`, in `STUDIO_STYLES` order). Glyph-like styles (`ascii`, `blocks`, `braille`, `lines`, `cross`, `diagonal`, `diamond`, `mixed`) bring their ramp, which a `charset` beside them overrides; `dots` is the halftone mark; the rest (`pixel`, `mosaic`, `lego`, `voxel`, `disco`, `dither`, `hex`, `led`, `cmyk`, `stipple`, `engraving`, `crosshatch`, `woodblock`, `risograph`, `pointillism`) switch the field's `mark` and keep each field's own charset, which decides the cells left blank. Unknown styles and empty charsets are dropped. Dot fields skip the look, except backgrounds such as `swell` that are made to take characters. `setGlobalLook(null)` gives each field its own mark and characters back.
194
194
 
195
195
  `setGlobalLook({ charset })` balances the set's weight against classic ASCII: block and solid sets draw smaller glyphs so they keep detail, sets without light glyphs (binary) ease off, and faint sets (minimal, braille, code) draw larger, bolder glyphs; tones are untouched. A look applies to every glyph field, live or released, except dot marks, fields whose own `charset` holds letters (a word or a brand, such as `wordmark`), and fields created with `globalLook: false` (use it for a locked region). An empty `charset` keeps each field's own. `getGlobalLook()` reads the current look, so `subscribeGlobalLook` pairs with React's `useSyncExternalStore`.
196
196
 
@@ -479,52 +479,41 @@ Options: `onRefresh` (may return a promise; the ring spins at least 600ms), `con
479
479
 
480
480
  ## Backgrounds
481
481
 
482
- Every background on asciify.org/backgrounds as one call, drawn the same way as the site's stage: the same renderers, clock, pointer smoothing, pixel ratio and graphite inks, so a preset with the same settings matches it in light and dark. The canvas sits under the element's content (`isolation: isolate`, `z-index: -1`), follows the theme, pauses off screen and in hidden tabs, and holds one still frame under reduced motion.
482
+ The curated backgrounds on asciify.org/backgrounds as one call each. They are scenes of the GPU glyph field, so they follow `setGlobalLook` (the header's characters and the 24 render styles) like every field component, keep a quiet zone for your copy, take `lazy`, `poster`, `globalLook` and the context budget, and hold one still frame under reduced motion. The canvas sits under the element's content (`isolation: isolate`, `z-index: -1`), follows the theme and pauses off screen and in hidden tabs.
483
483
 
484
484
  ```ts
485
- import { background, caustics, aurora } from 'asciify-engine/kit';
485
+ import { background, halo, swell } from 'asciify-engine/kit';
486
486
 
487
- const bg = background(hero, { preset: caustics, clear: headline, speed: 0.8 });
487
+ const bg = background(hero, { preset: halo, clear: headline, speed: 0.8 });
488
488
  bg.update({ palette: { light: '#5b4bd1', dark: '#8f80ff' }, cellSize: 10 });
489
- bg.setPreset(aurora); // cross-fades, keeping your options
490
- ```
491
-
492
- Presets are separate exports, so a page pays only for the ones it imports: `background()` with one canvas preset is about 6.2 KB gzip (6.8 KB for `wave`), and each further canvas preset adds 0.2–0.9 KB (all 22 together: 13.9 KB). `drift`, `halftone`, `swell`, `wordField` and `fluid` drive the GPU glyph field, so they cost about 7 KB (`fluid` 9.7 KB) plus the shared `asciify-engine/field` build, 17 KB gzip, that every field component uses (and take `lazy`, `poster`, `globalLook` and the context budget like every field component); the rest are 2D canvases and need no WebGL. To offer a menu of several, import those you list.
493
-
494
- Options: `preset` (required), `palette` (one ink or `{ light, dark }`, winning over `color` and `ink`; default the preset's graphite for the ground), `color` (one ink for both grounds), `accent` (heads, peaks and signals for the presets that draw them; default the preset's own, or one mixed from the ink), `speed` (0–5, default the preset's tuned pace, the Speed control on the site), `cellSize` (character size in CSS px, dot spacing for `halftone` and `swell`; default the preset's), `charset` (characters from empty to dense, or a named set: `standard`, `asciify`, `minimal`, `detailed`, `letters`, `technical`, `blocks`, `braille`, `dots`), `cursor` (pointer response, default on for the presets that answer it; the GPU presets also take `'trail' | 'fluid' | 'lantern'`), `clear` (an element to keep clear: the field fades out round it), `opacity` (default 1, `fluid` 0.7, `swell` 0.6), `dither` (ordered dither 0–1 for the tonal presets), `text` (`wordField`'s word, default `ASCIIFY`), plus `ink`, `look` (glyph-field settings, GPU presets only) and `reducedMotion`. Methods: `setPreset(preset)`; getter `preset`. `field` is the `GlyphField` for the GPU presets and `null` for canvas ones.
495
-
496
- `fluid` lays its cells out as the site's hero does: a whole number of 7 × 12.07 px cells (`cellSize` / 0.58 tall) stretched to fill the stage exactly, so rows keep their place down a tall page, drawn at up to 1.5 device pixels per CSS pixel. It does this through the field's `cellFit: 'fill'` (see glyph-field.md).
497
-
498
- The canvas templates draw in the page's fonts: load Geist Mono (and JetBrains Mono for `fluid`) as the site does, and note that the page's `-webkit-font-smoothing` changes their weight on macOS just as it does on the site.
499
-
500
- | Preset | Kind | Looks like | Size, speed, cursor |
501
- | --- | --- | --- | --- |
502
- | `drift` | GPU | Characters that drift slowly in broad soft lobes and clear round your content | 11, 1, trail |
503
- | `halftone` | GPU | The same drifting ground as dots | 14, 1, lantern |
504
- | `swell` | GPU | A fine dot grid whose dots swell in slow rolling waves, quiet in the middle and clear round your content; dots rise under the pointer and settle behind it | 10, 1, lantern |
505
- | `wordField` | GPU | Your word (`text`) as a flowing field of letters | 13, 1, trail |
506
- | `fluid` | GPU | The original Asciify hero: flowing folds with a wake behind the cursor | 7, 1, wake |
507
- | `caustics` | canvas | Fine pools of light drifting like water across stone | 12, 1, no |
508
- | `contour` | canvas | Fine topographic lines with a slow, rolling drift | 12, 1, no |
509
- | `facet` | canvas | Folded planes catching light along their edges | 12, 1, no |
510
- | `etch` | canvas | Cut-grain lines following a sculpted current | 12, 1, no |
511
- | `moire` | canvas | Two fine line fields overlapping into broad bands | 12, 1, no |
512
- | `weave` | canvas | Interlaced threads with a subtle change in tension | 12, 1, no |
513
- | `veil` | canvas | Tall folds of light across a quiet ground | 12, 1, no |
514
- | `dune` | canvas | Layered sand ridges with slow light and fine grain | 12, 1, no |
515
- | `wave` | canvas | An interference field with a soft vortex at the cursor | 13, 0.6, yes |
516
- | `aurora` | canvas | Soft bands of light that ripple under the cursor | 13, 0.6, yes |
517
- | `noise` | canvas | A slow fractal noise field that warps round the cursor | 13, 0.5, yes |
518
- | `silk` | canvas | Long ribbons following a slow flow field | 13, 1, no |
519
- | `rain` | canvas | Columns of falling characters with bright heads | 13, 1, no |
520
- | `stars` | canvas | A sparse starfield that twinkles and leans to the cursor | 14, 1, yes |
521
- | `pulse` | canvas | Rings of characters rippling out from the cursor | 14, 1, yes |
522
- | `grid` | canvas | Scan bands rolling down a grid, glitching near the cursor | 12, 1, yes |
523
- | `voidWell` | canvas | A gravity well spiralling characters round the cursor (`void` is reserved in JS) | 13, 1, yes |
524
- | `morph` | canvas | Every cell shimmering at its own frequencies | 14, 1, no |
525
- | `fire` | canvas | A cellular flame rising from the bottom edge | 13, 1, no |
526
- | `dna` | canvas | Double helices scrolling past with base-pair letters | 13, 1, no |
527
- | `terrain` | canvas | A side-scrolling landscape in density characters | 13, 1, no |
528
- | `circuit` | canvas | Circuit traces with signals running along them | 13, 1, no |
489
+ bg.setPreset(swell); // cross-fades, keeping your options
490
+ bg.update({ cursor: false }); // no pointer response, for any preset
491
+ ```
492
+
493
+ Presets are separate exports, so a page pays only for the ones it imports. Each GPU preset is a small object over the shared `asciify-engine/field` build (about 23 KB gzip) that every field component uses; `fluid` adds its solver (about 3 KB). To offer a menu of several, import those you list.
494
+
495
+ Options: `preset` (required), `palette` (one ink or `{ light, dark }`, winning over `color` and `ink`; default the preset's graphite for the ground), `color` (one ink for both grounds), `speed` (0–5, default the preset's tuned pace, the Speed control on the site), `cellSize` (character size in CSS px, dot spacing for dots; default the preset's), `charset` (characters from empty to dense, or a named set: `standard`, `asciify`, `minimal`, `detailed`, `letters`, `technical`, `blocks`, `braille`, `dots`; on a dot preset it asks for characters), `mark` (`'glyph'` or `'dot'`; default the preset's own), `cursor` (pointer response: `false` turns it off, `true` keeps the preset's own, or name `'trail' | 'fluid' | 'lantern'`; a `look.hover` of `'none'` also turns it off), `clear` (an element to keep clear: the field fades out round it; without one each preset keeps its own quiet middle), `opacity` (default 1, `fluid` 0.7, `swell` 0.6), `text` (`wordField`'s word, default `ASCIIFY`), plus `ink`, `look` (raw glyph-field settings on top, such as `{ mark: 'stipple' }` for a render style) and `reducedMotion`. Methods: `setPreset(preset)`; getter `preset`; `field` is the preset's `GlyphField` (for `field.pulse()`).
496
+
497
+ `swell` draws halftone dots by default. `mark: 'glyph'` or a `charset` writes the same waves in characters (Geist Mono cells, 0.62 wide), and a global look does the same while it is set: a charset or glyph-like style gives it characters, a tile or print style its mark, and `setGlobalLook(null)` gives it its dots back. Every other preset draws characters by default and takes `mark: 'dot'` for a halftone.
498
+
499
+ `fluid` lays its cells out as the site's hero does: a whole number of 7 × 12.07 px cells (`cellSize` / 0.58 tall) stretched to fill the stage exactly, so rows keep their place down a tall page, drawn at up to 1.5 device pixels per CSS pixel. It does this through the field's `cellFit: 'fill'` (see glyph-field.md), and parts round `clear`.
500
+
501
+ | Preset | Looks like | Size, speed, pointer |
502
+ | --- | --- | --- |
503
+ | `swell` | A fine grid swelling in slow rolling waves, quiet in the middle; dots by default, or characters | 10, 1, lantern |
504
+ | `drift` | Characters drifting slowly in broad soft lobes, clear round your content | 11, 1, trail |
505
+ | `halo` | A corona breathing slowly round the middle, its rays turning; the centre stays empty for a headline | 11, 1, lantern |
506
+ | `caustics` | Light focused by moving water: fine bright lines that fold, part and meet | 11, 1, lantern |
507
+ | `contour` | Survey lines over a slowly shifting terrain, one character wide, every fifth an index line | 11, 1, lantern |
508
+ | `aurora` | Curtains of light folding across the top, sharp along their hems | 11, 1, lantern |
509
+ | `ripple` | Still water: drops ring outward here and there; the pointer drops its own (`field.pulse`) | 11, 1, drops |
510
+ | `mesh` | Four soft lights on slow paths, a gradient mesh across the whole ramp | 11, 1, trail |
511
+ | `interference` | Two ring grids from orbiting centres; moiré bands open and close where they cross | 11, 1, lantern |
512
+ | `constellation` | Points wandering in their cells, close neighbours linked by fine lines | 11, 1, lantern |
513
+ | `cascade` | Streaks falling in three depths: far ones faint and slow, near ones bright and quick | 11, 1, lantern |
514
+ | `wordField` | Your word (`text`) as a flowing field of letters | 13, 1, trail |
515
+ | `fluid` | The original Asciify hero: flowing folds with a wake behind the cursor | 7, 1, wake |
516
+
517
+ Retired presets are still exported, marked `@deprecated`, so code that imports them keeps running unchanged; they are no longer shown on the site or in these docs. Move to the closest current one: `halftone` → `drift` with `mark: 'dot'` (`cellSize: 14`), `dna` and `voidWell` → `halo`, `circuit` and `stars` → `constellation`, `fire`, `silk` and `veil` → `aurora`, `grid`, `weave` and `moire` → `interference`, `morph` and `noise` → `mesh`, `pulse` → `ripple`, `rain` → `cascade`, `terrain`, `dune` and `etch` → `contour`, `facet` → `caustics`, `wave` → `swell`. The retired canvas presets draw on a 2D canvas and also take `accent` and `dither`.
529
518
 
530
519
  Your own preset is an object with `id`, `name`, `description`, `cellSize`, `speed`, `cursor` and `mount(context)`; `mountCanvas(context, draw)` runs a 2D template with the same clock and pointer as the built-ins.