asciify-engine 4.12.1 → 4.14.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.
@@ -1,76 +1,5 @@
1
1
  import { A as AmbientMotion, S as SurfaceHover } from './hover-catalog-D85jh6dR.cjs';
2
2
 
3
- /** Curated ASCII ramps, each ordered by measured glyph ink from empty to dense so tone reads evenly.
4
- * Use custom text to supply a different alphabet. */
5
- declare const CHARACTER_SETS: {
6
- readonly standard: {
7
- readonly label: "Classic ASCII";
8
- readonly chars: " .:-=+*#%@";
9
- };
10
- readonly asciify: {
11
- readonly label: "Asciify";
12
- readonly chars: " .:-=+YCIFSA#@";
13
- };
14
- readonly minimal: {
15
- readonly label: "Minimal";
16
- readonly chars: " .:+";
17
- };
18
- readonly detailed: {
19
- readonly label: "Detailed";
20
- readonly chars: " .,:;itLf1CG80@";
21
- };
22
- readonly letters: {
23
- readonly label: "Letters";
24
- readonly chars: " .liLTYCFSAWM";
25
- };
26
- readonly technical: {
27
- readonly label: "Technical";
28
- readonly chars: " ._:;+/>=][{}*$#@";
29
- };
30
- readonly blocks: {
31
- readonly label: "Tonal blocks";
32
- readonly chars: " ░▒▓█";
33
- };
34
- readonly braille: {
35
- readonly label: "Braille";
36
- readonly chars: " ⠁⠃⠇⡇⣇⣧⣷⣿";
37
- };
38
- };
39
- declare const STUDIO_CHARACTER_SETS: {
40
- readonly standard: {
41
- readonly label: "Classic ASCII";
42
- readonly chars: " .:-=+*#%@";
43
- };
44
- readonly asciify: {
45
- readonly label: "Asciify";
46
- readonly chars: " .:-=+YCIFSA#@";
47
- };
48
- readonly minimal: {
49
- readonly label: "Minimal";
50
- readonly chars: " .:+";
51
- };
52
- readonly detailed: {
53
- readonly label: "Detailed";
54
- readonly chars: " .,:;itLf1CG80@";
55
- };
56
- readonly letters: {
57
- readonly label: "Letters";
58
- readonly chars: " .liLTYCFSAWM";
59
- };
60
- readonly technical: {
61
- readonly label: "Technical";
62
- readonly chars: " ._:;+/>=][{}*$#@";
63
- };
64
- readonly blocks: {
65
- readonly label: "Tonal blocks";
66
- readonly chars: " ░▒▓█";
67
- };
68
- readonly braille: {
69
- readonly label: "Braille";
70
- readonly chars: " ⠁⠃⠇⡇⣇⣧⣷⣿";
71
- };
72
- };
73
-
74
3
  /** Input/output coordinates use 0–1. Curves have at most 16 points, including endpoints. */
75
4
  type StudioCurvePoint = [number, number];
76
5
  declare const STUDIO_CURVE_CHANNELS: readonly ["rgb", "red", "green", "blue"];
@@ -350,4 +279,4 @@ declare function studioGrid(width: number, height: number, settings: Pick<Studio
350
279
  limited: boolean;
351
280
  };
352
281
 
353
- export { normalizeStudioPrint as A, BLEND_MODES as B, CHARACTER_SETS as C, DEFAULT_STUDIO_PRINT as D, normalizeStudioSettings as E, normalizeStudioWarps as F, parseStudioSettings as G, serializeStudioSettings as H, studioCrop as I, studioDimensions as J, studioGrid as K, updateStudioSettings as L, MAX_STUDIO_WARPS as M, type StudioSettings as S, type StudioInput as a, DEFAULT_STUDIO_SETTINGS as b, DITHER_ALGORITHMS as c, type DitherAlgorithm as d, STUDIO_CHARACTER_SETS as e, STUDIO_CURVE_CHANNELS as f, STUDIO_PALETTES as g, STUDIO_PRINT_STYLES as h, STUDIO_PRINT_STYLE_IDS as i, STUDIO_STYLES as j, STUDIO_WARPS as k, type StudioCurveChannel as l, type StudioCurvePoint as m, type StudioCurves as n, type StudioLight as o, type StudioMask as p, type StudioPrintSettings as q, type StudioPrintStyle as r, type StudioStyle as s, type StudioWarp as t, type StudioWarpEdge as u, type StudioWarpType as v, createStudioCurveLookup as w, isStudioPrintStyle as x, normalizeStudioCurve as y, normalizeStudioCurves as z };
282
+ export { normalizeStudioSettings as A, BLEND_MODES as B, normalizeStudioWarps as C, DEFAULT_STUDIO_PRINT as D, parseStudioSettings as E, serializeStudioSettings as F, studioCrop as G, studioDimensions as H, studioGrid as I, updateStudioSettings as J, MAX_STUDIO_WARPS as M, type StudioSettings as S, type StudioInput as a, DEFAULT_STUDIO_SETTINGS as b, DITHER_ALGORITHMS as c, type DitherAlgorithm as d, STUDIO_CURVE_CHANNELS as e, STUDIO_PALETTES as f, STUDIO_PRINT_STYLES as g, STUDIO_PRINT_STYLE_IDS as h, STUDIO_STYLES as i, STUDIO_WARPS as j, type StudioCurveChannel as k, type StudioCurvePoint as l, type StudioCurves as m, type StudioLight as n, type StudioMask as o, type StudioPrintSettings as p, type StudioPrintStyle as q, type StudioStyle as r, type StudioWarp as s, type StudioWarpEdge as t, type StudioWarpType as u, createStudioCurveLookup as v, isStudioPrintStyle as w, normalizeStudioCurve as x, normalizeStudioCurves as y, normalizeStudioPrint as z };
@@ -1,76 +1,5 @@
1
1
  import { A as AmbientMotion, S as SurfaceHover } from './hover-catalog-D85jh6dR.js';
2
2
 
3
- /** Curated ASCII ramps, each ordered by measured glyph ink from empty to dense so tone reads evenly.
4
- * Use custom text to supply a different alphabet. */
5
- declare const CHARACTER_SETS: {
6
- readonly standard: {
7
- readonly label: "Classic ASCII";
8
- readonly chars: " .:-=+*#%@";
9
- };
10
- readonly asciify: {
11
- readonly label: "Asciify";
12
- readonly chars: " .:-=+YCIFSA#@";
13
- };
14
- readonly minimal: {
15
- readonly label: "Minimal";
16
- readonly chars: " .:+";
17
- };
18
- readonly detailed: {
19
- readonly label: "Detailed";
20
- readonly chars: " .,:;itLf1CG80@";
21
- };
22
- readonly letters: {
23
- readonly label: "Letters";
24
- readonly chars: " .liLTYCFSAWM";
25
- };
26
- readonly technical: {
27
- readonly label: "Technical";
28
- readonly chars: " ._:;+/>=][{}*$#@";
29
- };
30
- readonly blocks: {
31
- readonly label: "Tonal blocks";
32
- readonly chars: " ░▒▓█";
33
- };
34
- readonly braille: {
35
- readonly label: "Braille";
36
- readonly chars: " ⠁⠃⠇⡇⣇⣧⣷⣿";
37
- };
38
- };
39
- declare const STUDIO_CHARACTER_SETS: {
40
- readonly standard: {
41
- readonly label: "Classic ASCII";
42
- readonly chars: " .:-=+*#%@";
43
- };
44
- readonly asciify: {
45
- readonly label: "Asciify";
46
- readonly chars: " .:-=+YCIFSA#@";
47
- };
48
- readonly minimal: {
49
- readonly label: "Minimal";
50
- readonly chars: " .:+";
51
- };
52
- readonly detailed: {
53
- readonly label: "Detailed";
54
- readonly chars: " .,:;itLf1CG80@";
55
- };
56
- readonly letters: {
57
- readonly label: "Letters";
58
- readonly chars: " .liLTYCFSAWM";
59
- };
60
- readonly technical: {
61
- readonly label: "Technical";
62
- readonly chars: " ._:;+/>=][{}*$#@";
63
- };
64
- readonly blocks: {
65
- readonly label: "Tonal blocks";
66
- readonly chars: " ░▒▓█";
67
- };
68
- readonly braille: {
69
- readonly label: "Braille";
70
- readonly chars: " ⠁⠃⠇⡇⣇⣧⣷⣿";
71
- };
72
- };
73
-
74
3
  /** Input/output coordinates use 0–1. Curves have at most 16 points, including endpoints. */
75
4
  type StudioCurvePoint = [number, number];
76
5
  declare const STUDIO_CURVE_CHANNELS: readonly ["rgb", "red", "green", "blue"];
@@ -350,4 +279,4 @@ declare function studioGrid(width: number, height: number, settings: Pick<Studio
350
279
  limited: boolean;
351
280
  };
352
281
 
353
- export { normalizeStudioPrint as A, BLEND_MODES as B, CHARACTER_SETS as C, DEFAULT_STUDIO_PRINT as D, normalizeStudioSettings as E, normalizeStudioWarps as F, parseStudioSettings as G, serializeStudioSettings as H, studioCrop as I, studioDimensions as J, studioGrid as K, updateStudioSettings as L, MAX_STUDIO_WARPS as M, type StudioSettings as S, type StudioInput as a, DEFAULT_STUDIO_SETTINGS as b, DITHER_ALGORITHMS as c, type DitherAlgorithm as d, STUDIO_CHARACTER_SETS as e, STUDIO_CURVE_CHANNELS as f, STUDIO_PALETTES as g, STUDIO_PRINT_STYLES as h, STUDIO_PRINT_STYLE_IDS as i, STUDIO_STYLES as j, STUDIO_WARPS as k, type StudioCurveChannel as l, type StudioCurvePoint as m, type StudioCurves as n, type StudioLight as o, type StudioMask as p, type StudioPrintSettings as q, type StudioPrintStyle as r, type StudioStyle as s, type StudioWarp as t, type StudioWarpEdge as u, type StudioWarpType as v, createStudioCurveLookup as w, isStudioPrintStyle as x, normalizeStudioCurve as y, normalizeStudioCurves as z };
282
+ export { normalizeStudioSettings as A, BLEND_MODES as B, normalizeStudioWarps as C, DEFAULT_STUDIO_PRINT as D, parseStudioSettings as E, serializeStudioSettings as F, studioCrop as G, studioDimensions as H, studioGrid as I, updateStudioSettings as J, MAX_STUDIO_WARPS as M, type StudioSettings as S, type StudioInput as a, DEFAULT_STUDIO_SETTINGS as b, DITHER_ALGORITHMS as c, type DitherAlgorithm as d, STUDIO_CURVE_CHANNELS as e, STUDIO_PALETTES as f, STUDIO_PRINT_STYLES as g, STUDIO_PRINT_STYLE_IDS as h, STUDIO_STYLES as i, STUDIO_WARPS as j, type StudioCurveChannel as k, type StudioCurvePoint as l, type StudioCurves as m, type StudioLight as n, type StudioMask as o, type StudioPrintSettings as p, type StudioPrintStyle as q, type StudioStyle as r, type StudioWarp as s, type StudioWarpEdge as t, type StudioWarpType as u, createStudioCurveLookup as v, isStudioPrintStyle as w, normalizeStudioCurve as x, normalizeStudioCurves as y, normalizeStudioPrint as z };
package/dist/studio.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as StudioSettings, a as StudioInput, B as BLEND_MODES } from './model-B0jK31nS.cjs';
2
- export { C as CHARACTER_SETS, D as DEFAULT_STUDIO_PRINT, b as DEFAULT_STUDIO_SETTINGS, c as DITHER_ALGORITHMS, d as DitherAlgorithm, M as MAX_STUDIO_WARPS, e as STUDIO_CHARACTER_SETS, f as STUDIO_CURVE_CHANNELS, g as STUDIO_PALETTES, h as STUDIO_PRINT_STYLES, i as STUDIO_PRINT_STYLE_IDS, j as STUDIO_STYLES, k as STUDIO_WARPS, l as StudioCurveChannel, m as StudioCurvePoint, n as StudioCurves, o as StudioLight, p as StudioMask, q as StudioPrintSettings, r as StudioPrintStyle, s as StudioStyle, t as StudioWarp, u as StudioWarpEdge, v as StudioWarpType, w as createStudioCurveLookup, x as isStudioPrintStyle, y as normalizeStudioCurve, z as normalizeStudioCurves, A as normalizeStudioPrint, E as normalizeStudioSettings, F as normalizeStudioWarps, G as parseStudioSettings, H as serializeStudioSettings, I as studioCrop, J as studioDimensions, K as studioGrid, L as updateStudioSettings } from './model-B0jK31nS.cjs';
1
+ import { S as StudioSettings, a as StudioInput, B as BLEND_MODES } from './model-9SbRVqqI.cjs';
2
+ export { D as DEFAULT_STUDIO_PRINT, b as DEFAULT_STUDIO_SETTINGS, c as DITHER_ALGORITHMS, d as DitherAlgorithm, M as MAX_STUDIO_WARPS, e as STUDIO_CURVE_CHANNELS, f as STUDIO_PALETTES, g as STUDIO_PRINT_STYLES, h as STUDIO_PRINT_STYLE_IDS, i as STUDIO_STYLES, j as STUDIO_WARPS, k as StudioCurveChannel, l as StudioCurvePoint, m as StudioCurves, n as StudioLight, o as StudioMask, p as StudioPrintSettings, q as StudioPrintStyle, r as StudioStyle, s as StudioWarp, t as StudioWarpEdge, u as StudioWarpType, v as createStudioCurveLookup, w as isStudioPrintStyle, x as normalizeStudioCurve, y as normalizeStudioCurves, z as normalizeStudioPrint, A as normalizeStudioSettings, C as normalizeStudioWarps, E as parseStudioSettings, F as serializeStudioSettings, G as studioCrop, H as studioDimensions, I as studioGrid, J as updateStudioSettings } from './model-9SbRVqqI.cjs';
3
3
  import * as figlet_fonts_Wavy from 'figlet/fonts/Wavy';
4
4
  import * as figlet_fonts_Univers from 'figlet/fonts/Univers';
5
5
  import * as figlet_fonts_3_D from 'figlet/fonts/3-D';
@@ -21,6 +21,7 @@ import * as figlet_fonts_Big from 'figlet/fonts/Big';
21
21
  import * as figlet_fonts_Small from 'figlet/fonts/Small';
22
22
  import * as figlet_fonts_Slant from 'figlet/fonts/Slant';
23
23
  import * as figlet_fonts_Standard from 'figlet/fonts/Standard';
24
+ export { C as CHARACTER_SETS, S as STUDIO_CHARACTER_SETS } from './characters-BgG9AZQl.cjs';
24
25
  export { a as STUDIO_HOVERS, M as STUDIO_MOTIONS } from './hover-catalog-D85jh6dR.cjs';
25
26
  export { S as STUDIO_ANIMATION_PRESETS, a as StudioAnimationPreset } from './animation-presets-DhswE0D_.cjs';
26
27
 
package/dist/studio.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as StudioSettings, a as StudioInput, B as BLEND_MODES } from './model-BARiWJks.js';
2
- export { C as CHARACTER_SETS, D as DEFAULT_STUDIO_PRINT, b as DEFAULT_STUDIO_SETTINGS, c as DITHER_ALGORITHMS, d as DitherAlgorithm, M as MAX_STUDIO_WARPS, e as STUDIO_CHARACTER_SETS, f as STUDIO_CURVE_CHANNELS, g as STUDIO_PALETTES, h as STUDIO_PRINT_STYLES, i as STUDIO_PRINT_STYLE_IDS, j as STUDIO_STYLES, k as STUDIO_WARPS, l as StudioCurveChannel, m as StudioCurvePoint, n as StudioCurves, o as StudioLight, p as StudioMask, q as StudioPrintSettings, r as StudioPrintStyle, s as StudioStyle, t as StudioWarp, u as StudioWarpEdge, v as StudioWarpType, w as createStudioCurveLookup, x as isStudioPrintStyle, y as normalizeStudioCurve, z as normalizeStudioCurves, A as normalizeStudioPrint, E as normalizeStudioSettings, F as normalizeStudioWarps, G as parseStudioSettings, H as serializeStudioSettings, I as studioCrop, J as studioDimensions, K as studioGrid, L as updateStudioSettings } from './model-BARiWJks.js';
1
+ import { S as StudioSettings, a as StudioInput, B as BLEND_MODES } from './model-DXHhQhxP.js';
2
+ export { D as DEFAULT_STUDIO_PRINT, b as DEFAULT_STUDIO_SETTINGS, c as DITHER_ALGORITHMS, d as DitherAlgorithm, M as MAX_STUDIO_WARPS, e as STUDIO_CURVE_CHANNELS, f as STUDIO_PALETTES, g as STUDIO_PRINT_STYLES, h as STUDIO_PRINT_STYLE_IDS, i as STUDIO_STYLES, j as STUDIO_WARPS, k as StudioCurveChannel, l as StudioCurvePoint, m as StudioCurves, n as StudioLight, o as StudioMask, p as StudioPrintSettings, q as StudioPrintStyle, r as StudioStyle, s as StudioWarp, t as StudioWarpEdge, u as StudioWarpType, v as createStudioCurveLookup, w as isStudioPrintStyle, x as normalizeStudioCurve, y as normalizeStudioCurves, z as normalizeStudioPrint, A as normalizeStudioSettings, C as normalizeStudioWarps, E as parseStudioSettings, F as serializeStudioSettings, G as studioCrop, H as studioDimensions, I as studioGrid, J as updateStudioSettings } from './model-DXHhQhxP.js';
3
3
  import * as figlet_fonts_Wavy from 'figlet/fonts/Wavy';
4
4
  import * as figlet_fonts_Univers from 'figlet/fonts/Univers';
5
5
  import * as figlet_fonts_3_D from 'figlet/fonts/3-D';
@@ -21,6 +21,7 @@ import * as figlet_fonts_Big from 'figlet/fonts/Big';
21
21
  import * as figlet_fonts_Small from 'figlet/fonts/Small';
22
22
  import * as figlet_fonts_Slant from 'figlet/fonts/Slant';
23
23
  import * as figlet_fonts_Standard from 'figlet/fonts/Standard';
24
+ export { C as CHARACTER_SETS, S as STUDIO_CHARACTER_SETS } from './characters-BgG9AZQl.js';
24
25
  export { a as STUDIO_HOVERS, M as STUDIO_MOTIONS } from './hover-catalog-D85jh6dR.js';
25
26
  export { S as STUDIO_ANIMATION_PRESETS, a as StudioAnimationPreset } from './animation-presets-ZujFF3i8.js';
26
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asciify-engine",
3
- "version": "4.12.1",
3
+ "version": "4.14.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",
@@ -56,6 +56,16 @@
56
56
  "types": "./dist/field.d.cts",
57
57
  "default": "./dist/field.cjs"
58
58
  }
59
+ },
60
+ "./kit": {
61
+ "import": {
62
+ "types": "./dist/kit.d.ts",
63
+ "default": "./dist/kit.js"
64
+ },
65
+ "require": {
66
+ "types": "./dist/kit.d.cts",
67
+ "default": "./dist/kit.cjs"
68
+ }
59
69
  }
60
70
  },
61
71
  "files": [
@@ -1,50 +1,80 @@
1
1
  ---
2
2
  name: asciify-engine
3
- description: Build and tune browser ASCII art with asciify-engine so it fits the user's request, preferences and the project's design. Use for photo, video and GIF conversion, interactive heroes, GPU character fields with the user's own words, ambient backgrounds, text banners, art styles and export, hover and motion choices, layered HTML typography, and rendering performance.
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, art styles and export, hover and motion, layered typography and rendering performance.
4
4
  metadata:
5
- tested-engine: "4.12.1"
6
- updated: "2026-10-14"
5
+ tested-engine: "4.14.0"
6
+ updated: "2026-10-17"
7
7
  ---
8
8
 
9
9
  # Asciify Engine
10
10
 
11
- Use the published `asciify-engine` npm package for browser canvas rendering. Tested against **4.12.1**. 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.14.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
- - Playground: https://asciify.org/editor
15
- - API documentation: https://asciify.org/docs/api
14
+ - Components: https://asciify.org/components · Backgrounds: https://asciify.org/backgrounds
15
+ - Playground: https://asciify.org/editor · API documentation: https://asciify.org/docs/api
16
16
  - Repository: https://github.com/ayangabryl/asciify-engine
17
17
 
18
18
  ```sh
19
19
  npm install asciify-engine@latest
20
20
  ```
21
21
 
22
- Entries: `asciify-engine` and `/core` for media and text conversion; `/hover` for the website hovers and living-image motion; `/studio` for art styles, looks and export; `/field` for GPU character fields. Each optional entry loads only when imported. Procedural background templates are downloaded from asciify.org/backgrounds and are not npm exports. GIF decoding loads `gifuct-js` when a GIF API is called.
22
+ Entries: `/kit` for interface components and backgrounds, one call each; `asciify-engine` and `/core` for media and text conversion; `/hover` for the website hovers and living-image motion; `/studio` for art styles, looks and export; `/field` for raw GPU character fields. Each optional entry loads only when imported. GIF decoding loads `gifuct-js` when a GIF API is called.
23
23
 
24
- ## Start here: the request, then the design
24
+ ## Start here: kit first
25
25
 
26
- Most requests are a feeling ("make the hero feel alive", "retro", "subtle behind the pricing", "like unseen.co, with our name") rather than an API. Before writing code:
26
+ Most requests are a feeling ("make the loading state feel alive", "a calm background behind pricing", "like asciify.org") rather than an API. Work in this order:
27
27
 
28
- 1. **Read the request.** Subject (their media, a word, or nothing), placement (hero, background behind text, card, banner), mood words, interaction, and any reference site.
29
- 2. **Read the design.** Open the project's tokens (CSS custom properties, Tailwind theme, brand file): page background, text colors, the one accent, mono and display fonts, light/dark themes, motion durations and easing, reduced-motion handling.
30
- 3. **Pick the tool** from the table below, then **derive every color, font and size from the tokens**. Never add a new brand color, a black canvas on a light site, or a white hover glow on a colored artwork.
31
- 4. **Decide living or still.** A still photo can be made to feel alive (field `drift`, studio `motion`), but some users want it still. Follow their words; keep art behind text, in grids and in data views still; reduced motion always gets a still. See [living or still](references/design-matching.md#living-or-still).
28
+ 1. **Is it a UI component or a background?** Almost always, yes. Read [applying-asciify.md](references/applying-asciify.md) (the house design: when characters earn a place, ink, the clear zone and veil, density, radii, motion, performance, accessibility, which background suits which surface), then take the call from [components.md](references/components.md) and its options from [kit.md](references/kit.md). Stop there unless the kit has no option for the look.
29
+ 2. **Read the request.** Subject (their media, a word, or nothing), placement (hero, card, control, background behind text), mood words, interaction, any reference site.
30
+ 3. **Read the design.** Open the project's tokens: ground and surface colours, text colours, the one accent, mono and display fonts, radii, light and dark themes, motion durations and easing, reduced-motion handling. Map the kit's ink tokens (`--ascii-ink`, `--ascii-ink-strong`, `--ascii-success`, `--ascii-warning`, `--ascii-error`) onto them; never add a brand colour.
31
+ 4. **Decide living or still.** Follow the user's words; keep art behind text, in grids and in data views still; reduced motion always gets a still. See [living or still](references/design-matching.md#living-or-still).
32
32
  5. **Say what you chose in one line** and offer one alternative. Ask only when the media is missing or motion would be new to a site that has none.
33
33
 
34
- [references/components.md](references/components.md) has 29 ready-made components with a shared theme-aware helper: controls (button loading, slide to confirm, like burst, verification code, command palette), feedback (loading states, skeleton loader, toast stack, pull to refresh), AI (voice orb, thinking, streaming text, image generation), transitions (page transition, delete into characters), data (chart, odometer, border beam), media (before and after, dropzone, accordion, swipe cards, video), text (decode headline, wordmark) and pages (sign-in, pricing, 404, hero background), each with the prompt a person gives and the reference code. Start there when the request matches one.
35
-
36
- [references/design-matching.md](references/design-matching.md) maps mood words to settings, explains light themes, contrast and fonts, and gives tested recipes for the common requests. Read it whenever the user describes a look rather than an option.
34
+ [design-matching.md](references/design-matching.md) maps mood words to settings for the lower-level APIs and media looks.
37
35
 
38
36
  | The user wants | Use |
39
37
  | --- | --- |
40
- | Their photo, video or GIF as ASCII on the page, optionally answering the cursor | `asciify` / `asciifyVideo` / `asciifyGif`, plus `mountHover` from `/hover` for the website hovers |
41
- | A full-bleed hero or brand field that stays smooth under the cursor, or their own word as the characters | `mountGlyphField` from `/field` ([glyph-field.md](references/glyph-field.md)); `hover: 'trail'` for the classic Asciify Trail on pure characters, `'fluid'` for bold and liquid, `'lantern'` for a subtle light |
42
- | A calm background behind product content (SaaS hero, pricing, docs), light or dark | `mountGlyphField` with `mark: 'dot'`, `scene: 'drift'`, `clear` around the copy, and `pulse()` on events (4.12) |
43
- | Art styles, saved looks, backdrops, masks, effects, PNG/MP4/GIF export | `mountStudio` from `/studio` ([studio-workspace.md](references/studio-workspace.md)) |
44
- | Several media and text layers in one artwork | `mountStudioProject` from `/studio` ([layered-projects.md](references/layered-projects.md)) |
45
- | An ambient background with no media | A template from asciify.org/backgrounds, or a `/field` generated scene |
46
- | A text banner or lettering | `asciifyText` / `renderTextToCanvas` |
47
- | Headline text visible through the art | Layered HTML ([layered-hero.md](references/layered-hero.md)) |
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 |
40
+ | Their word or brand in characters | Kit `wordmark`, or `background()` with `wordField` |
41
+ | Their video in characters on the page | Kit `asciiVideo` |
42
+ | Their photo, video or GIF converted, optionally answering the cursor | Advanced: `asciify` / `asciifyVideo` / `asciifyGif`, plus `mountHover` from `/hover` |
43
+ | A full-bleed field with a look the kit has no option for | Advanced: `mountGlyphField` from `/field` ([glyph-field.md](references/glyph-field.md)) |
44
+ | Art styles, saved looks, masks, effects, PNG/MP4/GIF export | Advanced: `mountStudio` from `/studio` ([studio-workspace.md](references/studio-workspace.md)) |
45
+ | Several media and text layers in one artwork | Advanced: `mountStudioProject` from `/studio` ([layered-projects.md](references/layered-projects.md)) |
46
+ | A text banner or lettering | Advanced: `asciifyText` / `renderTextToCanvas` |
47
+ | Headline text visible through media art | Advanced: layered HTML ([layered-hero.md](references/layered-hero.md)) |
48
+
49
+ ## The kit in one paragraph
50
+
51
+ Each kit function mounts an `aria-hidden` field over or inside your element, follows its size and border radius, inks it from your theme in light and dark, pauses off screen, honours reduced motion, falls back without WebGL2 to an inert handle that leaves your HTML working, and cleans up on `destroy()`. components.md has 31 components as short snippets with the prompt a person gives, in categories Components, AI, Text, Transitions, Media, Pages and Backgrounds. In React, create the handle in an effect and return its `destroy`.
52
+
53
+ ```ts
54
+ import { beam } from 'asciify-engine/kit';
55
+ const b = beam(card, { palette: 'mono', mode: 'pulse' });
56
+ // On unmount: b.destroy();
57
+ ```
58
+
59
+ `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
+
61
+ ## Backgrounds
62
+
63
+ `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
+
65
+ ```ts
66
+ import { background, halftone } from 'asciify-engine/kit';
67
+ const bg = background(pricing, { preset: halftone, clear: pricingCopy });
68
+ ```
69
+
70
+ The 26 presets, as export → `id` (name):
71
+
72
+ - GPU glyph field (WebGL2, shares the context budget): `drift` → `drift` (Drift), `halftone` → `halftone` (Halftone), `wordField` → `field` (Field), `fluid` → `fluid` (Fluid).
73
+ - 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).
74
+
75
+ `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.
76
+
77
+ Downloaded templates from asciify.org/backgrounds (`asciiBackground` from a local `./wave.js`) still work in apps that already use them; new work uses `background()`.
48
78
 
49
79
  ## Install the agent skill
50
80
 
@@ -54,15 +84,23 @@ npx skills add ayangabryl/asciify-engine --skill asciify-engine
54
84
 
55
85
  This uses the Vercel Skills CLI to install the repository skill and its linked resources. The npm dependency and an installed agent skill update separately. When asked to update Asciify or when an integration needs newer options, follow [references/upgrading.md](references/upgrading.md): check npm's current `latest`, update with the project's package manager, then refresh only this skill in its installed scope. Do not treat this document's tested version as permanently latest, or upgrade unrelated skills/dependencies.
56
86
 
87
+ ## Verify before handing off
88
+
89
+ Run the checklist at the end of [applying-asciify.md](references/applying-asciify.md#10-checklist-before-you-finish) for kit work. For any integration, check the real page: readable subject and text in both themes, no stretching or unintended margins, working pointer and keyboard controls, mobile crop, reduced motion, autoplay failure, WebGL off, and cleanup after navigation. Observe several seconds of motion and a loop boundary. State the measured device and settings with any FPS figure; screenshots alone do not establish performance.
90
+
91
+ Do not import nonexistent helpers such as `createRecorder` or `recordAndDownload`.
92
+
93
+ # Advanced: the lower-level APIs
94
+
95
+ Use these when the request is media conversion, art styles or export, or a field look the kit cannot give. They do not handle theme ink, posters, the context budget or fallbacks for you; the rules in applying-asciify.md still apply to the result.
96
+
57
97
  ## Choose the integration
58
98
 
59
99
  For a live project component, start with [project-integration.md](references/project-integration.md): it maps each use case to one rendering pipeline, covers instance ownership, and keeps PNG/video export independent of live playback. Use `/studio` for a new composition with art styles, masks, backdrops and saved settings. It already owns hover/motion; do not add another `/hover` instance on top.
60
100
 
61
-
62
101
  - Static image: `asciify(source, canvas, config)` returns `Promise<() => void>`. Call the cleanup on unmount, including for a still image.
63
102
  - Video: `asciifyVideo(source, canvas, config)` returns `Promise<() => void>`. Call that function on unmount. Use `fitTo` and `objectFit: 'cover'` for full-bleed heroes; `contain` for a whole-subject preview.
64
103
  - GIF: `asciifyGif(source, canvas, config)` returns a cleanup function asynchronously.
65
- - Procedural background: download a template from https://asciify.org/backgrounds and import its `asciiBackground` helper locally. Call its `destroy()` on unmount. No background generators ship in npm 4.0.
66
104
  - Dense custom rendering: use `imageToAsciiTextFrame` and `renderTextFrameToCanvas`; keep the same options when converting and rendering. Use object frames when per-cell mutation is required.
67
105
 
68
106
  For a hero with HTML layered through the ASCII, read [references/layered-hero.md](references/layered-hero.md) and use the accompanying [HTML](examples/layered-hero.html), [CSS](examples/layered-hero.css), and [JavaScript](examples/layered-hero.js). These are ordinary Vite/bundler inputs, not another npm dependency. Supply your own media.
@@ -111,7 +149,7 @@ const letters = [...new Set('ASCIIFY'.toUpperCase().replace(/[^A-Z]/g, ''))].joi
111
149
  const charset = ` .:-=+${letters}#%@`;
112
150
  ```
113
151
 
114
- Preview it: letter glyph densities differ, so arbitrary words are not automatically an evenly ordered ramp. When the user wants the artwork drawn in their name, `/field` handles it better: put the word after a quiet ramp (`' .,:-+' + word`), use one ink with `shade: 1`, and let brightness carry the image (see [design-matching.md](references/design-matching.md)). Keep the leading space and the light/dense symbols. Use the curated `CHARACTER_SETS.standard.chars`, `detailed.chars`, `blocks.chars`, or `braille.chars` from `/core` when appropriate.
152
+ Preview it: letter glyph densities differ, so arbitrary words are not automatically an evenly ordered ramp. When the user wants the artwork drawn in their name, the kit's `wordmark` or `wordField` background does it; on raw `/field`, put the word after a quiet ramp (`' .,:-+' + word`), use one ink with `shade: 1`, and let brightness carry the image (see [design-matching.md](references/design-matching.md)). Keep the leading space and the light/dense symbols. Use the curated `CHARACTER_SETS.standard.chars`, `detailed.chars`, `blocks.chars`, or `braille.chars` from `/core` when appropriate.
115
153
 
116
154
  ## Engine effects versus studio effects
117
155
 
@@ -123,25 +161,21 @@ To reproduce those interactions, read [references/studio-effects.md](references/
123
161
 
124
162
  For built-in hover alone, use a supported `options.hoverEffect` and a restrained nonzero `hoverStrength`; validate its behavior instead of promising that it matches the website.
125
163
 
126
- ## Text layering
127
-
128
- Use real HTML for the headline, description, and links. The engine draws artwork; CSS controls which HTML sits in front of it.
164
+ ## Text layering over media art
129
165
 
130
- For our cover relationship, use a single isolated hero stacking context:
166
+ For interface grounds, text sits on a clear zone and a frosted veil ([applying-asciify.md](references/applying-asciify.md#3-text-over-a-field-clear-zone-plus-frosted-veil)). For a media hero where the headline should read through the artwork, use real HTML and a single isolated hero stacking context:
131
167
 
132
168
  1. Headline at `z-index: 0`.
133
169
  2. Transparent ASCII canvas/stage at `z-index: 1`.
134
170
  3. Description, CTA, and motion controls at `z-index: 2` or above.
135
171
 
136
- Keep these as sibling layers. A transformed or isolated content wrapper can trap all its descendants below the canvas. Set decorative artwork to `pointer-events: none`; attach optional hover input to the positioned hero host. Keep controls clickable, focusable, and visually unobscured. Leave canvas background transparent; an opaque canvas or stage hides the headline beneath it.
137
-
138
- Choose the more conventional arrangement—artwork behind all text—when it improves readability. The layered example explains both arrangements without imposing the Asciify homepage's branding or layout on another project.
172
+ Keep these as sibling layers. A transformed or isolated content wrapper can trap all its descendants below the canvas. Set decorative artwork to `pointer-events: none`; attach optional hover input to the positioned hero host. Keep controls clickable, focusable, and visually unobscured. Leave canvas background transparent; an opaque canvas or stage hides the headline beneath it. Choose artwork behind all text when it reads better.
139
173
 
140
174
  ## Performance and lifecycle
141
175
 
142
176
  - Reduce processing dimensions and cell count before dropping source playback FPS. Do not default to 60 fps on a 24 fps video.
143
177
  - Start video at 24–30 fps with a 720–960px processing cap. More processing pixels do not create detail absent from the source.
144
- - When the user asks for a smooth, high-frame-rate hero, prefer `/field` over a canvas pipeline, and keep the canvas pipeline as its fallback.
178
+ - When the user asks for a smooth, high-frame-rate hero, prefer the kit or `/field` over a canvas pipeline, and keep the canvas pipeline as its fallback.
145
179
  - Keep stable canvas dimensions; resize on layout changes, not on every animation frame.
146
180
  - Avoid remounting the renderer on pointer movement or each React render.
147
181
  - Pause media offscreen and when the document is hidden. Reduced-motion users should get a still; do not merely hide a playing video with CSS.
@@ -149,13 +183,7 @@ Choose the more conventional arrangement—artwork behind all text—when it imp
149
183
  - Compress media at a resolution appropriate to ASCII sampling, remove unused audio, use fast-start MP4, and provide a small poster. Immutable caching requires a content-hashed URL; keep this skill's URL revalidatable.
150
184
  - Fine dithering can add texture but can shimmer on moving footage. Compare a still and a loop, and offer a non-dithered rendering.
151
185
  - YouTube page URLs and iframe players are not direct canvas video sources. Use permitted direct media files with suitable CORS; see https://asciify.org/docs/youtube.
152
-
153
- ## Verify before handing off
154
-
155
- Check the actual implementation: readable subject and text, no stretching or unintended empty margins, working pointer and keyboard controls, mobile crop, reduced motion, autoplay failure, and cleanup after navigation. Observe several seconds of motion and an entire loop boundary. State the measured device/settings if reporting FPS; screenshots and recordings alone do not establish performance.
156
-
157
- Do not import nonexistent helpers such as `createRecorder` or `recordAndDownload`. For deterministic composition export, use `/studio` as described below. For recording an existing interactive canvas, use a browser `MediaRecorder` with a supported `canvas.captureStream()` format and clean up its tracks; for snapshots, inspect the published `captureSnapshot` / `snapshotAndDownload` types.
158
-
186
+ - For deterministic composition export, use `/studio`. To record an existing interactive canvas, use a browser `MediaRecorder` with a supported `canvas.captureStream()` format and clean up its tracks; for snapshots, inspect the published `captureSnapshot` / `snapshotAndDownload` types.
159
187
 
160
188
  ## Hero finish
161
189
 
@@ -167,7 +195,7 @@ For optional wallpaper/backdrops, alternate renderers, palettes, masks, saved lo
167
195
 
168
196
  ## GPU glyph fields
169
197
 
170
- For a full-bleed hero, section background or brand field that must stay smooth under the cursor, use `mountGlyphField` from `asciify-engine/field` and read [references/glyph-field.md](references/glyph-field.md). It draws glyph ramps (including words and braille) from images, video or generated motion on WebGL2 with a fluid wake that keeps each character's own color. It does not replace `/studio` for the 24 render styles, dither, print styles, effects or export. Check `isGlyphFieldSupported()` (false without a GPU), always provide a poster and a canvas fallback, and call `destroy()` on unmount.
198
+ The kit is built on `mountGlyphField` from `asciify-engine/field`. Use it directly only for a look the kit has no option for, and read [references/glyph-field.md](references/glyph-field.md) and the raw-field helper at the end of [components.md](references/components.md#advanced-raw-field). It draws glyph ramps (including words and braille) from images, video or generated motion on WebGL2 with a fluid wake. It does not replace `/studio` for the 24 render styles, dither, print styles, effects or export. Check `isGlyphFieldSupported()`, provide a poster and a fallback, honour reduced motion, and call `destroy()` on unmount. To build your own component with the kit's plumbing instead, use `mountSurface` ([kit.md](references/kit.md#your-own-components)).
171
199
 
172
200
  ## Current catalogs
173
201
 
@@ -175,7 +203,6 @@ For multiple media/text layers in one live component, use 4.8+ `mountStudioProje
175
203
 
176
204
  Legacy `CHARSETS`, `ART_STYLE_PRESETS`, `CHARSET_SEQUENCES`, `LIVING_STYLE_PRESETS` and their key types are removed. Do not import them or generate old names such as Katakana, Binary, Waves or Smoke. Use the 24 `STUDIO_STYLES` for render-style selectors and `/studio` rendering. For ASCII-only character ramps use `CHARACTER_SETS` from `/core` or `STUDIO_CHARACTER_SETS` from `/studio`; custom Unicode and user-provided frame arrays remain supported. Core `artStyle` only accepts `classic`; use explicit options instead of preset shortcuts. Despite the requested 4.1.0 version number, migrating these removed APIs is a breaking change.
177
205
 
178
-
179
206
  ## Version notes
180
207
 
181
208
  Read these when the installed version is older than the tested one, or when a user names a specific feature.
@@ -196,10 +223,10 @@ From 4.9, optional Studio adds Stipple, Engraving, Crosshatch, Woodblock, Risogr
196
223
 
197
224
  `STUDIO_ANIMATION_PRESETS` provides six editable motion/hover pairings through `/studio` and `/hover`. Apply `motion` and `hover` to an existing Studio player to keep the source and art style; do not treat the pairings as additional art styles. Read [studio-effects.md](references/studio-effects.md#lively-images-410) for exact new IDs, loop limits and the live component example.
198
225
 
199
- ### GPU glyph fields (4.11)
226
+ ### GPU glyph fields (4.11) and the kit (4.13)
200
227
 
201
- `asciify-engine/field` adds `mountGlyphField`, `isGlyphFieldSupported` and `glyphFieldTier`. Older installs do not have this entry; upgrade before using it.
228
+ `asciify-engine/field` adds `mountGlyphField`, `isGlyphFieldSupported` and `glyphFieldTier` in 4.11; `mark`, `clear` and `pulse()` in 4.12. `asciify-engine/kit` arrives in 4.13; `background()` and its presets, `lazy`, `poster`, the context budget and the global look follow it. Older installs do not have these entries; upgrade before using them.
202
229
 
203
230
  ## Scenario prompts
204
231
 
205
- Use [scenario-prompts.md](references/scenario-prompts.md) for copyable briefs covering images, heroes, characters, all styles, dither, backgrounds, video/GIF, scroll, layers, text, export, frameworks, procedural trails, reference matching, troubleshooting, upgrades, saved looks and accessibility. Adapt the prompt to the user’s intent; do not add unrelated features. Use the published renderer’s native Trail; do not add a separate tonal ribbon overlay.
232
+ Use [scenario-prompts.md](references/scenario-prompts.md) for copyable briefs covering images, heroes, characters, all styles, dither, backgrounds, video/GIF, scroll, layers, text, export, frameworks, procedural trails, reference matching, troubleshooting, upgrades, saved looks and accessibility. Adapt the prompt to the user's intent; do not add unrelated features. Use the published renderer's native Trail; do not add a separate tonal ribbon overlay.