@pixerate/editor 0.145.0 → 0.147.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.
Files changed (135) hide show
  1. package/README.md +4 -2
  2. package/THIRD_PARTY_NOTICES.md +1 -1
  3. package/dist/agent/index.cjs +36 -34
  4. package/dist/agent/index.js +7 -5
  5. package/dist/animation/index.cjs +5 -3
  6. package/dist/animation/index.js +4 -2
  7. package/dist/animation-editor/index.cjs +62 -60
  8. package/dist/animation-editor/index.js +6 -4
  9. package/dist/canvas/index.cjs +36 -34
  10. package/dist/canvas/index.js +19 -17
  11. package/dist/chart/index.cjs +88 -86
  12. package/dist/chart/index.js +7 -5
  13. package/dist/{chunk-WBJ6BG4R.js → chunk-2AQL4JHM.js} +6 -6
  14. package/dist/{chunk-HLMF3E53.cjs → chunk-2WDZI6QD.cjs} +15 -15
  15. package/dist/{chunk-ZNHB5RG6.js → chunk-37RLSNQ3.js} +2 -2
  16. package/dist/{chunk-5WOY52O6.cjs → chunk-4YQKRHMI.cjs} +8 -8
  17. package/dist/chunk-6ONMQ6WF.js +113 -0
  18. package/dist/{chunk-L434J57V.cjs → chunk-6QTON3VW.cjs} +16 -16
  19. package/dist/chunk-AA34BA7G.js +1913 -0
  20. package/dist/{chunk-QX25HWFL.js → chunk-AY65VQSU.js} +1 -1
  21. package/dist/{chunk-ONZJD2OD.cjs → chunk-BROJYMWU.cjs} +57 -153
  22. package/dist/{chunk-YM75DN54.js → chunk-DSZCDNTM.js} +1 -1
  23. package/dist/{chunk-PUR6BZFA.cjs → chunk-DVLMW3GB.cjs} +53 -53
  24. package/dist/{chunk-ALUWD3FG.js → chunk-EIUTJPEL.js} +1 -1
  25. package/dist/{chunk-X65C4DWV.js → chunk-EQ4SF4X4.js} +1 -1
  26. package/dist/{chunk-77SG47WT.js → chunk-FLOGD3QB.js} +1 -1
  27. package/dist/chunk-HRLT5BYO.js +133 -0
  28. package/dist/{chunk-AJSW5GMP.js → chunk-HVQVHUTV.js} +19 -115
  29. package/dist/{chunk-UR37VCIR.cjs → chunk-I4AHLP7F.cjs} +16 -35
  30. package/dist/chunk-IPJ3TEYR.cjs +113 -0
  31. package/dist/chunk-KC7HB5GF.cjs +133 -0
  32. package/dist/chunk-KY3FYKP3.js +52 -0
  33. package/dist/chunk-LEUZ4FRC.cjs +52 -0
  34. package/dist/{chunk-H6FX45CP.cjs → chunk-LIXLD433.cjs} +37 -37
  35. package/dist/{chunk-6GAYGQDC.js → chunk-O5ML2I6O.js} +3 -3
  36. package/dist/{chunk-KI2VBONS.js → chunk-OET45HIR.js} +2 -2
  37. package/dist/{chunk-XNZWATSB.cjs → chunk-QCEQIRJQ.cjs} +85 -85
  38. package/dist/{chunk-HRI3ZMDM.cjs → chunk-RHXW4TA5.cjs} +3 -3
  39. package/dist/{chunk-UUTTJK77.cjs → chunk-SUF6WRXR.cjs} +2 -2
  40. package/dist/{chunk-RN767PO6.js → chunk-SUVZJ2CP.js} +15 -34
  41. package/dist/{chunk-FLUTRPLY.cjs → chunk-TLMRGLQQ.cjs} +16 -16
  42. package/dist/{chunk-DAS7M4RY.js → chunk-UILRJQFD.js} +2 -2
  43. package/dist/chunk-UKCJ43YL.cjs +1913 -0
  44. package/dist/{chunk-XQ33O5BC.cjs → chunk-X35BV5YT.cjs} +44 -44
  45. package/dist/{chunk-6HMEHNWW.cjs → chunk-XTU6QO2W.cjs} +26 -26
  46. package/dist/{chunk-VM6JYWXQ.js → chunk-ZQUANEK4.js} +2 -2
  47. package/dist/cms/index.cjs +5 -3
  48. package/dist/cms/index.js +18 -16
  49. package/dist/color/contrast.d.cts +14 -0
  50. package/dist/color/contrast.d.ts +14 -0
  51. package/dist/color/convert.d.cts +30 -0
  52. package/dist/color/convert.d.ts +30 -0
  53. package/dist/color/dual.d.cts +98 -0
  54. package/dist/color/dual.d.ts +98 -0
  55. package/dist/color/format.d.cts +12 -0
  56. package/dist/color/format.d.ts +12 -0
  57. package/dist/color/gamut.d.cts +12 -0
  58. package/dist/color/gamut.d.ts +12 -0
  59. package/dist/color/harmony.d.cts +22 -0
  60. package/dist/color/harmony.d.ts +22 -0
  61. package/dist/color/index.cjs +115 -0
  62. package/dist/color/index.d.cts +18 -0
  63. package/dist/color/index.d.ts +18 -0
  64. package/dist/color/index.js +115 -0
  65. package/dist/color/mix.d.cts +11 -0
  66. package/dist/color/mix.d.ts +11 -0
  67. package/dist/color/named.d.cts +5 -0
  68. package/dist/color/named.d.ts +5 -0
  69. package/dist/color/parse.d.cts +11 -0
  70. package/dist/color/parse.d.ts +11 -0
  71. package/dist/color/picker.d.cts +52 -0
  72. package/dist/color/picker.d.ts +52 -0
  73. package/dist/color/recent.d.cts +8 -0
  74. package/dist/color/recent.d.ts +8 -0
  75. package/dist/color/tools.d.cts +15 -0
  76. package/dist/color/tools.d.ts +15 -0
  77. package/dist/color/types.d.cts +41 -0
  78. package/dist/color/types.d.ts +41 -0
  79. package/dist/color/vision.d.cts +36 -0
  80. package/dist/color/vision.d.ts +36 -0
  81. package/dist/diagram/editorDocument.d.cts +12 -0
  82. package/dist/diagram/editorDocument.d.ts +12 -0
  83. package/dist/diagram/index.cjs +35 -1
  84. package/dist/diagram/index.d.cts +1 -0
  85. package/dist/diagram/index.d.ts +1 -0
  86. package/dist/diagram/index.js +34 -0
  87. package/dist/export/index.cjs +6 -4
  88. package/dist/export/index.js +5 -3
  89. package/dist/extensions/index.cjs +10 -8
  90. package/dist/extensions/index.js +9 -7
  91. package/dist/gradient/controller.d.cts +109 -0
  92. package/dist/gradient/controller.d.ts +109 -0
  93. package/dist/gradient/editor.d.cts +38 -0
  94. package/dist/gradient/editor.d.ts +38 -0
  95. package/dist/gradient/index.cjs +1549 -0
  96. package/dist/gradient/index.d.cts +5 -0
  97. package/dist/gradient/index.d.ts +5 -0
  98. package/dist/gradient/index.js +1549 -0
  99. package/dist/gradient/model.d.cts +94 -0
  100. package/dist/gradient/model.d.ts +94 -0
  101. package/dist/gradient/tools.d.cts +11 -0
  102. package/dist/gradient/tools.d.ts +11 -0
  103. package/dist/gradient/types.d.cts +44 -0
  104. package/dist/gradient/types.d.ts +44 -0
  105. package/dist/image-editor/index.cjs +649 -647
  106. package/dist/image-editor/index.js +6 -4
  107. package/dist/index.cjs +19 -17
  108. package/dist/index.js +16 -14
  109. package/dist/paint-editor/color.d.cts +3 -13
  110. package/dist/paint-editor/color.d.ts +3 -13
  111. package/dist/paint-editor/index.cjs +23 -68
  112. package/dist/paint-editor/index.js +15 -60
  113. package/dist/persistence/documentStore.d.cts +51 -0
  114. package/dist/persistence/documentStore.d.ts +51 -0
  115. package/dist/persistence/documentTools.d.cts +35 -0
  116. package/dist/persistence/documentTools.d.ts +35 -0
  117. package/dist/persistence/editorAutosave.d.cts +33 -0
  118. package/dist/persistence/editorAutosave.d.ts +33 -0
  119. package/dist/persistence/editorDocument.d.cts +118 -0
  120. package/dist/persistence/editorDocument.d.ts +118 -0
  121. package/dist/persistence/index.cjs +294 -1
  122. package/dist/persistence/index.d.cts +4 -0
  123. package/dist/persistence/index.d.ts +4 -0
  124. package/dist/persistence/index.js +293 -0
  125. package/dist/vector/index.cjs +950 -948
  126. package/dist/vector/index.js +5 -3
  127. package/dist/video-editor/index.cjs +5 -3
  128. package/dist/video-editor/index.js +4 -2
  129. package/package.json +21 -1
  130. package/skills/README.md +1 -0
  131. package/skills/pixerate-agent-tools/SKILL.md +21 -0
  132. package/skills/pixerate-color/SKILL.md +69 -0
  133. package/skills/pixerate-diagram/SKILL.md +13 -0
  134. package/dist/chunk-45VRG4RB.js +0 -65
  135. package/dist/chunk-5FXOR7F2.cjs +0 -65
@@ -38,7 +38,7 @@ import {
38
38
  reverseMorphContour,
39
39
  subpathToMorphContour,
40
40
  turnMorphContour
41
- } from "../chunk-DAS7M4RY.js";
41
+ } from "../chunk-UILRJQFD.js";
42
42
  import {
43
43
  DEFAULT_VECTOR_FONT,
44
44
  IDENTITY_MATRIX,
@@ -507,7 +507,7 @@ import {
507
507
  withVectorStrokes,
508
508
  withVectorTargetPaint,
509
509
  zigzagPaths
510
- } from "../chunk-77SG47WT.js";
510
+ } from "../chunk-FLOGD3QB.js";
511
511
  import "../chunk-ORDXMBD4.js";
512
512
  import {
513
513
  createProvenance
@@ -562,10 +562,12 @@ import {
562
562
  HistoryManager
563
563
  } from "../chunk-RNSANXPT.js";
564
564
  import "../chunk-5UJHB3BW.js";
565
- import "../chunk-45VRG4RB.js";
565
+ import "../chunk-KY3FYKP3.js";
566
566
  import {
567
567
  hexToRgba
568
568
  } from "../chunk-2WPNAGHI.js";
569
+ import "../chunk-AA34BA7G.js";
570
+ import "../chunk-6ONMQ6WF.js";
569
571
 
570
572
  // src/vector/trace.ts
571
573
  var VECTOR_TRACE_MAX_PIXELS = 4e6;
@@ -150,10 +150,12 @@ require('../chunk-WOFXZ3XU.cjs');
150
150
  var _chunkFJ2MSI43cjs = require('../chunk-FJ2MSI43.cjs');
151
151
 
152
152
 
153
- var _chunkUUTTJK77cjs = require('../chunk-UUTTJK77.cjs');
153
+ var _chunkSUF6WRXRcjs = require('../chunk-SUF6WRXR.cjs');
154
154
  require('../chunk-DWJJI6RT.cjs');
155
- require('../chunk-5FXOR7F2.cjs');
155
+ require('../chunk-LEUZ4FRC.cjs');
156
156
  require('../chunk-A6QWKBJP.cjs');
157
+ require('../chunk-UKCJ43YL.cjs');
158
+ require('../chunk-IPJ3TEYR.cjs');
157
159
 
158
160
  // src/video-editor/parse.ts
159
161
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
@@ -2807,7 +2809,7 @@ var VideoEditorController = (_class6 = class {
2807
2809
  this.readOnly = _nullishCoalesce(options.readOnly, () => ( false));
2808
2810
  this.previewScale = checkPreviewScale(_nullishCoalesce(options.previewScale, () => ( "auto")));
2809
2811
  this.onChange = options.onChange;
2810
- this.player = new (0, _chunkUUTTJK77cjs.AnimationPlayer)({ clock: options.clock, duration: () => _chunkVKF3PWKRcjs.videoProjectDuration.call(void 0, this.project), loop: "none" });
2812
+ this.player = new (0, _chunkSUF6WRXRcjs.AnimationPlayer)({ clock: options.clock, duration: () => _chunkVKF3PWKRcjs.videoProjectDuration.call(void 0, this.project), loop: "none" });
2811
2813
  this.state = this.computeState();
2812
2814
  this.connect();
2813
2815
  }
@@ -150,10 +150,12 @@ import {
150
150
  } from "../chunk-RNSANXPT.js";
151
151
  import {
152
152
  AnimationPlayer
153
- } from "../chunk-QX25HWFL.js";
153
+ } from "../chunk-AY65VQSU.js";
154
154
  import "../chunk-5UJHB3BW.js";
155
- import "../chunk-45VRG4RB.js";
155
+ import "../chunk-KY3FYKP3.js";
156
156
  import "../chunk-2WPNAGHI.js";
157
+ import "../chunk-AA34BA7G.js";
158
+ import "../chunk-6ONMQ6WF.js";
157
159
 
158
160
  // src/video-editor/parse.ts
159
161
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor",
3
- "version": "0.145.0",
3
+ "version": "0.147.0",
4
4
  "description": "UI-agnostic rich text and media editing core library",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -234,6 +234,26 @@
234
234
  "default": "./dist/tokens/index.cjs"
235
235
  }
236
236
  },
237
+ "./color": {
238
+ "import": {
239
+ "types": "./dist/color/index.d.ts",
240
+ "default": "./dist/color/index.js"
241
+ },
242
+ "require": {
243
+ "types": "./dist/color/index.d.cts",
244
+ "default": "./dist/color/index.cjs"
245
+ }
246
+ },
247
+ "./gradient": {
248
+ "import": {
249
+ "types": "./dist/gradient/index.d.ts",
250
+ "default": "./dist/gradient/index.js"
251
+ },
252
+ "require": {
253
+ "types": "./dist/gradient/index.d.cts",
254
+ "default": "./dist/gradient/index.cjs"
255
+ }
256
+ },
237
257
  "./export": {
238
258
  "import": {
239
259
  "types": "./dist/export/index.d.ts",
package/skills/README.md CHANGED
@@ -20,6 +20,7 @@ that uses the tools can load the matching skill.
20
20
  | [`pixerate-video-editor`](pixerate-video-editor/SKILL.md) | Non-linear video editing: tracks, clips, transitions, export. |
21
21
  | [`pixerate-generation`](pixerate-generation/SKILL.md) | Planning, estimating and running paid media generation. |
22
22
  | [`pixerate-parameters`](pixerate-parameters/SKILL.md) | Effect parameters, presets and keyframes. |
23
+ | [`pixerate-color`](pixerate-color/SKILL.md) | Colour inspection, WCAG accessibility and contrast optimization, CVD simulation, palette audits, harmonies, and OKLab/OKLCH blends. |
23
24
 
24
25
  ## Using them
25
26
 
@@ -61,6 +61,27 @@ editor's, or (in discovery mode) only `list_toolsets`, `search_tools`, `enable_t
61
61
  6. **Undo your own mistakes** with the domain's `undo_*` tool or the `history.undo` command, not
62
62
  by hand-reverting with more edits.
63
63
 
64
+ ## Saving, loading and undo
65
+
66
+ Every editor can share the same document tools, named after its kind (`diagram`, `chart`,
67
+ `spreadsheet`...). The editor's skill lists the ones it has.
68
+
69
+ - `get_<kind>_document` returns the whole document as plain JSON
70
+ (`{ kind, formatVersion, revision, document }`). Use it to keep a copy before a risky change
71
+ or to hand the document on, not to read it: the editor's own read tools are smaller and more
72
+ precise. It refuses very large documents and says so.
73
+ - `load_<kind>_document` puts such a copy back. The document is checked first and nothing
74
+ changes when it does not fit. It is one undo step when the result says `undoable: true`.
75
+ - `undo_<kind>` / `redo_<kind>` step through the editor's history. They fail with
76
+ "Nothing to undo." / "Nothing to redo." when there is nothing to step over.
77
+ - With host storage: `save_<kind>_document` (by `name`; the same name replaces that copy),
78
+ `list_saved_<kind>_documents`, then `open_saved_<kind>_document` with a `key` from either.
79
+ Save when the user asks. Opening replaces the current document, so ask first when it has
80
+ changes the user has not saved.
81
+
82
+ A read-only document keeps its read tools; its write tools fail with the reason. `revision`
83
+ goes up on every change, so comparing two results tells you whether the document changed.
84
+
64
85
  ## Playback
65
86
 
66
87
  The host may act your calls out on screen (agent playback): your cursor glides to what a call
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: pixerate-color
3
+ description: How to inspect colours, check and optimize WCAG contrast and accessibility, check palette distinctness across colour-vision deficiencies, generate harmonic color palettes, and blend colours across OKLab, OKLCH, and sRGB color spaces. Use when asked to evaluate contrast, choose accessible colours, create colour palettes, simulate colour blindness, or blend colours.
4
+ ---
5
+
6
+ # Colour tools
7
+
8
+ The colour module provides DOM-free colour tools for inspection, WCAG accessibility validation, colour-vision deficiency simulation, palette audits, colour harmony suggestions, and perceptual blending.
9
+
10
+ ## Working method
11
+
12
+ 1. **Inspect and convert.** Run `inspect_color` to parse any hex, `rgb()`, `hsl()`, `oklch()`, or CSS named colour into standard formats (hex, rgb, hsl, oklch) and relative luminance, and to check if it fits within the sRGB gamut.
13
+ 2. **Validate contrast.** Use `check_color_contrast` to compare text foreground against a background surface. It checks against WCAG 2 AA (4.5:1 regular, 3:1 large) and AAA (7:1 regular, 4.5:1 large). If AA contrast fails, it automatically calculates and suggests an adjusted lightness in OKLCH that preserves the hue and chroma while meeting accessibility standards.
14
+ 3. **Audit palettes.** For multi-colour sets (such as chart series, UI accents, or status tags), run `check_color_palette` with the array of colours. This checks mutual perceptual distinctness under normal vision as well as protanopia, deuteranopia, and tritanopia, and verifies adequate contrast against the background surface.
15
+ 4. **Harmonies and palettes.** Run `suggest_color_harmony` with a base colour and harmony kind (`complementary`, `split-complementary`, `analogous`, `triadic`, `tetradic`, `square`, or `monochromatic`) using either standard RGB or artistic RYB colour wheels.
16
+ 5. **Perceptual blending.** Run `blend_colors` to interpolate between two colours in OKLab, OKLCH, sRGB, or sRGB-linear. Pass a factor `t` (0..1) for a single midpoint, or `steps` (2..32) for an even ramp.
17
+ 6. **Design dual colours (light and dark mode).**
18
+ - Design the light mode colour.
19
+ - Run `derive_dual_color` with the app's real surfaces to automatically generate an accessible dark mode counterpart that matches contrast.
20
+ - Run `check_dual_color_contrast` for each text and background pair across both modes.
21
+ - Fix whichever mode fails using the suggested lightness.
22
+ - Run `export_dual_colors_css` to output clean CSS custom properties using `light-dark()`, `@media (prefers-color-scheme: dark)`, or `.dark` class rules.
23
+ 7. **Inspect and edit gradients.**
24
+ - Run `get_gradient` to inspect the active gradient model, CSS output, SVG def markup, and dual-colour status.
25
+ - Run `check_gradient` to audit for crowded stops, banding risk, out-of-gamut colours, and text contrast along the ramp.
26
+ - Run `list_gradient_presets` and `apply_gradient_preset` to quickly set tested gradient compositions.
27
+ - Modify gradient structure using `set_gradient`, `set_gradient_geometry`, `add_gradient_stop`, `update_gradient_stop`, `remove_gradient_stop`, `reverse_gradient`, or `distribute_gradient_stops`.
28
+
29
+ ## Best practices
30
+
31
+ - **Accessibility first.** Always check text and icon contrast against the actual background surface. Use the suggested foreground colour when `passesAA` is false.
32
+ - **Check both modes every time.** When authoring themes, verify contrast in both light and dark modes. Never assume dark mode passes just because light mode does.
33
+ - **Don't simply invert lightness for brand colours.** When creating dark-mode variants, keep the hue and lower the chroma slightly rather than just inverting RGB channels.
34
+ - **Perceptual spaces.** Use OKLab / OKLCH for interpolation and distance metrics to avoid muddy midpoints and hue shifts common in linear RGB or HSL blending.
35
+ - **Palette distinctness.** In data visualizations and charts, ensure colours can be distinguished not only under normal vision but also under deuteranopia and protanopia.
36
+ - **Alpha in contrast checks.** A translucent foreground is composited over the background, and a translucent background over white, before the ratio is taken. If the real backdrop behind a translucent background isn't white, pass the opaque colour the user actually sees.
37
+
38
+ ## Tool reference
39
+
40
+ | Tool | When to use | Returns |
41
+ | --- | --- | --- |
42
+ | `inspect_color` | Inspects a colour string and converts between hex, rgb, hsl, and oklch, checking sRGB gamut and relative luminance | `{ hex, rgb, hsl, oklch, css, inSrgbGamut, relativeLuminance }` |
43
+ | `check_color_contrast` | Evaluates WCAG 2 contrast ratio between foreground and background, returning AA/AAA pass status and an OKLCH lightness suggestion if failing | `{ ratio, level, passesAA, passesAAA, suggestion? }` |
44
+ | `check_color_palette` | Audits an array of colours for pairwise distinctness across normal vision and CVD (protanopia, deuteranopia, tritanopia), and surface contrast | `{ ok, closest, contrast, issues, skipped }` |
45
+ | `suggest_color_harmony` | Generates harmonic colour combinations on RGB or RYB colour wheels | `{ colors: [{ hex, angle }] }` |
46
+ | `blend_colors` | Interpolates between two colours in OKLab, OKLCH, sRGB, or sRGB-linear at factor `t` or as an even `steps` ramp | `{ color }` or `{ colors }` |
47
+ | `derive_dual_color` | Automatically derives the opposing scheme colour (light or dark) from a base colour, optionally preserving contrast against background surfaces | `{ light, dark, css, contrast: { light, dark } }` |
48
+ | `check_dual_color_contrast` | Evaluates WCAG contrast compliance for a foreground and background dual colour across both light and dark modes, with suggestions | `{ light: { ratio, level }, dark: { ratio, level }, issues, suggestion? }` |
49
+ | `export_dual_colors_css` | Generates CSS custom properties for dual colours using light-dark(), media queries, or darkSelector class | `{ css }` |
50
+ | `get_gradient` | Returns the current gradient model, CSS string, SVG def, and dual status | `{ gradient, css, svgDef, isDual, selectedStopId, readOnly }` |
51
+ | `check_gradient` | Audits gradient for crowded stops, banding risk, out-of-gamut colours, and text contrast | `{ pass, issueCount, issues }` |
52
+ | `list_gradient_presets` | Returns the collection of built-in gradient presets | `{ presets: [{ id, name, category, css, gradient }] }` |
53
+ | `set_gradient` | Replaces the entire gradient with a new gradient object or CSS string | `{ gradient, css }` |
54
+ | `set_gradient_geometry` | Changes any of type, angle, center, shape, interpolation, repeating in one undo step; pass only the fields to change. Angle applies to linear and conic, center to radial and conic, shape to radial only; a field that doesn't fit the (new) type fails the whole call and changes nothing | `{ gradient, css }` |
55
+ | `add_gradient_stop` | Adds a new color stop to the gradient ramp | `{ stop, gradient, css }` |
56
+ | `update_gradient_stop` | Updates an existing stop's color, offset, or midpoint | `{ stop, gradient, css }` |
57
+ | `remove_gradient_stop` | Removes a color stop by ID | `{ gradient, css }` |
58
+ | `reverse_gradient` | Reverses the order and offsets of all stops | `{ gradient, css }` |
59
+ | `distribute_gradient_stops` | Evenly distributes all color stops between 0 and 1 | `{ gradient, css }` |
60
+ | `apply_gradient_preset` | Applies a built-in gradient preset by ID | `{ preset, gradient, css }` |
61
+
62
+ ## Pitfalls
63
+
64
+ - **`light-dark()` requires `color-scheme`.** CSS `light-dark()` only resolves the dark colour when `color-scheme: light dark;` is set on the element or an ancestor (such as `:root`). Without `color-scheme`, browsers always render the light colour.
65
+ - **JavaScript resolution required for non-CSS targets.** Canvas 2D, WebGL, SVG presentation attributes, and raster image exporters cannot read `light-dark()` strings; resolve them in JavaScript with `resolveColor(value, scheme)`.
66
+ - **Gamut clipping.** Colours specified in wide-gamut spaces (e.g. high-chroma OKLCH) will be mapped into sRGB for hex representations. Check `inSrgbGamut` if exact fidelity is required.
67
+ - **Large text thresholds.** WCAG allows 3:1 for large text (18pt / 24px or 14pt / 18.5px bold); pass `large: true` to avoid overly aggressive contrast suggestions.
68
+ - **Geometry fields depend on the type.** To make a radial circle, send `type: "radial"` and `shape: "circle"` in the same `set_gradient_geometry` call; sending `shape` to a linear gradient is an error.
69
+ - **Ramp steps bounds.** `blend_colors` requires `steps` to be between 2 and 32 when generating a ramp.
@@ -111,6 +111,19 @@ text-only families.
111
111
  | `undo_diagram` | Undo the last diagram edit; returns its label. |
112
112
  | `redo_diagram` | Redo the last undone diagram edit. |
113
113
 
114
+ ### Save and open
115
+
116
+ The host may add the shared document tools (see `pixerate-agent-tools`). A diagram document is
117
+ `{ source }`: the Mermaid text with its `%% @pixerate` layout comment.
118
+
119
+ | Tool | Use |
120
+ | --- | --- |
121
+ | `get_diagram_document` | Take a copy of the whole diagram as `{ kind, formatVersion, revision, document }` before a risky rewrite, or to hand it to another session. To read the diagram, use `get_diagram`. |
122
+ | `load_diagram_document` | Put back a copy from `get_diagram_document` (its `document`, or the whole result). Checked first; one undo step (`undo_diagram` brings the previous diagram back). For new Mermaid text use `load_diagram_mermaid`. |
123
+ | `save_diagram_document` | Save the diagram under a `name` in the host's storage (same name replaces that copy). Returns the `key`. Only listed when the host has storage. Save when the user asks, not after every edit. |
124
+ | `list_saved_diagram_documents` | List saved diagrams (`key`, `name`, `savedAt`), newest first. |
125
+ | `open_saved_diagram_document` | Replace the diagram with a saved one by `key` from the list. One undo step. Ask before opening over unsaved work the user has not saved. |
126
+
114
127
  ## Pitfalls
115
128
 
116
129
  - Ids are Mermaid ids, not labels. Always take them from `get_diagram` or from what a write
@@ -1,65 +0,0 @@
1
- import {
2
- hexToRgba,
3
- normalizeTokenColor,
4
- rgbaToHex
5
- } from "./chunk-2WPNAGHI.js";
6
-
7
- // src/animation/color.ts
8
- var toLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
9
- var toGamma = (c) => c <= 31308e-7 ? 12.92 * c : 1.055 * Math.sign(c) * Math.abs(c) ** (1 / 2.4) - 0.055;
10
- function rgbToOklab(r, g, b, alpha = 1) {
11
- const lr = toLinear(r);
12
- const lg = toLinear(g);
13
- const lb = toLinear(b);
14
- const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);
15
- const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);
16
- const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);
17
- return {
18
- l: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
19
- a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
20
- b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
21
- alpha
22
- };
23
- }
24
- function oklabToRgb(color) {
25
- const l_ = color.l + 0.3963377774 * color.a + 0.2158037573 * color.b;
26
- const m_ = color.l - 0.1055613458 * color.a - 0.0638541728 * color.b;
27
- const s_ = color.l - 0.0894841775 * color.a - 1.291485548 * color.b;
28
- const l = l_ ** 3;
29
- const m = m_ ** 3;
30
- const s = s_ ** 3;
31
- const clamp01 = (v) => Math.min(1, Math.max(0, v));
32
- return {
33
- r: clamp01(toGamma(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s)),
34
- g: clamp01(toGamma(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s)),
35
- b: clamp01(toGamma(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s)),
36
- a: clamp01(color.alpha)
37
- };
38
- }
39
- function parseOklab(input) {
40
- const hex = normalizeTokenColor(input);
41
- if (hex === null) return null;
42
- const c = hexToRgba(hex);
43
- return rgbToOklab(c.r, c.g, c.b, c.a);
44
- }
45
- function formatOklab(color) {
46
- const { r, g, b, a } = oklabToRgb(color);
47
- return rgbaToHex(r, g, b, a);
48
- }
49
- function mixColorsOklab(from, to, t) {
50
- const a = parseOklab(from);
51
- const b = parseOklab(to);
52
- if (!a || !b) return null;
53
- const alpha = a.alpha + (b.alpha - a.alpha) * t;
54
- const premul = (k) => a[k] * a.alpha + (b[k] * b.alpha - a[k] * a.alpha) * t;
55
- if (alpha <= 1e-9) return formatOklab({ l: a.l + (b.l - a.l) * t, a: 0, b: 0, alpha: 0 });
56
- return formatOklab({ l: premul("l") / alpha, a: premul("a") / alpha, b: premul("b") / alpha, alpha });
57
- }
58
-
59
- export {
60
- rgbToOklab,
61
- oklabToRgb,
62
- parseOklab,
63
- formatOklab,
64
- mixColorsOklab
65
- };
@@ -1,65 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
-
4
-
5
- var _chunkA6QWKBJPcjs = require('./chunk-A6QWKBJP.cjs');
6
-
7
- // src/animation/color.ts
8
- var toLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
9
- var toGamma = (c) => c <= 31308e-7 ? 12.92 * c : 1.055 * Math.sign(c) * Math.abs(c) ** (1 / 2.4) - 0.055;
10
- function rgbToOklab(r, g, b, alpha = 1) {
11
- const lr = toLinear(r);
12
- const lg = toLinear(g);
13
- const lb = toLinear(b);
14
- const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);
15
- const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);
16
- const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);
17
- return {
18
- l: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
19
- a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
20
- b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
21
- alpha
22
- };
23
- }
24
- function oklabToRgb(color) {
25
- const l_ = color.l + 0.3963377774 * color.a + 0.2158037573 * color.b;
26
- const m_ = color.l - 0.1055613458 * color.a - 0.0638541728 * color.b;
27
- const s_ = color.l - 0.0894841775 * color.a - 1.291485548 * color.b;
28
- const l = l_ ** 3;
29
- const m = m_ ** 3;
30
- const s = s_ ** 3;
31
- const clamp01 = (v) => Math.min(1, Math.max(0, v));
32
- return {
33
- r: clamp01(toGamma(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s)),
34
- g: clamp01(toGamma(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s)),
35
- b: clamp01(toGamma(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s)),
36
- a: clamp01(color.alpha)
37
- };
38
- }
39
- function parseOklab(input) {
40
- const hex = _chunkA6QWKBJPcjs.normalizeTokenColor.call(void 0, input);
41
- if (hex === null) return null;
42
- const c = _chunkA6QWKBJPcjs.hexToRgba.call(void 0, hex);
43
- return rgbToOklab(c.r, c.g, c.b, c.a);
44
- }
45
- function formatOklab(color) {
46
- const { r, g, b, a } = oklabToRgb(color);
47
- return _chunkA6QWKBJPcjs.rgbaToHex.call(void 0, r, g, b, a);
48
- }
49
- function mixColorsOklab(from, to, t) {
50
- const a = parseOklab(from);
51
- const b = parseOklab(to);
52
- if (!a || !b) return null;
53
- const alpha = a.alpha + (b.alpha - a.alpha) * t;
54
- const premul = (k) => a[k] * a.alpha + (b[k] * b.alpha - a[k] * a.alpha) * t;
55
- if (alpha <= 1e-9) return formatOklab({ l: a.l + (b.l - a.l) * t, a: 0, b: 0, alpha: 0 });
56
- return formatOklab({ l: premul("l") / alpha, a: premul("a") / alpha, b: premul("b") / alpha, alpha });
57
- }
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
- exports.rgbToOklab = rgbToOklab; exports.oklabToRgb = oklabToRgb; exports.parseOklab = parseOklab; exports.formatOklab = formatOklab; exports.mixColorsOklab = mixColorsOklab;