@fusion.dev/helix 0.7.2 → 0.8.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.
@@ -0,0 +1,150 @@
1
+ export const ORB_STATES = ['thinking', 'fetching', 'working', 'done'];
2
+ export const ORB_PARAMS = {
3
+ done: {
4
+ belt: 1,
5
+ edge: 0,
6
+ jitter: 1,
7
+ rate: 1.1,
8
+ rot: 0,
9
+ scan: 0,
10
+ shear: 0,
11
+ squash: 1,
12
+ waveA: 0,
13
+ waveB: 0,
14
+ },
15
+ fetching: {
16
+ belt: 1,
17
+ edge: 0,
18
+ jitter: 0,
19
+ rate: 2.4,
20
+ rot: 0,
21
+ scan: 1,
22
+ shear: 0,
23
+ squash: 1,
24
+ waveA: 0,
25
+ waveB: 0,
26
+ },
27
+ thinking: {
28
+ belt: 0.47,
29
+ edge: 1,
30
+ jitter: 0,
31
+ rate: 2.1,
32
+ rot: 1.52,
33
+ scan: 0,
34
+ shear: 0,
35
+ squash: 1,
36
+ waveA: 0.16,
37
+ waveB: 0.07,
38
+ },
39
+ working: {
40
+ belt: 1,
41
+ edge: 0,
42
+ jitter: 0,
43
+ rate: 2.4,
44
+ rot: 0.5,
45
+ scan: 0,
46
+ shear: 1.3,
47
+ squash: 0.72,
48
+ waveA: 0,
49
+ waveB: 0,
50
+ },
51
+ };
52
+ const KEYS = Object.keys(ORB_PARAMS.thinking);
53
+ export const blendParams = (a, b, k) => {
54
+ const out = {};
55
+ for (const key of KEYS) {
56
+ out[key] = a[key] + (b[key] - a[key]) * k;
57
+ }
58
+ return out;
59
+ };
60
+ export const paramsFor = (state) => ORB_PARAMS[state] ?? ORB_PARAMS.thinking;
61
+ const TAU = Math.PI * 2;
62
+ export const smoother = (t) => t * t * t * (t * (t * 6 - 15) + 10);
63
+ export const fibonacci = (i, n) => {
64
+ const k = Math.PI * (3 - Math.sqrt(5));
65
+ const y = 1 - (2 * (i + 0.5)) / n;
66
+ const r = Math.sqrt(Math.max(0, 1 - y * y));
67
+ return [r * Math.cos(i * k), y, r * Math.sin(i * k)];
68
+ };
69
+ const evenCache = new Map();
70
+ export const evenSphere = (lanes, segs) => {
71
+ const key = `${lanes}x${segs}`;
72
+ const hit = evenCache.get(key);
73
+ if (hit) {
74
+ return hit;
75
+ }
76
+ const total = lanes * segs;
77
+ const points = [];
78
+ for (let i = 0; i < total; i++) {
79
+ points.push(fibonacci(i, total));
80
+ }
81
+ points.sort((a, b) => a[1] - b[1]);
82
+ const azimuth = (q) => (Math.atan2(q[2], q[0]) + TAU) % TAU;
83
+ const out = new Array(total);
84
+ for (let b = 0; b < lanes; b++) {
85
+ const band = points.slice(b * segs, (b + 1) * segs);
86
+ band.sort((a, c) => azimuth(a) - azimuth(c));
87
+ for (let s = 0; s < segs; s++) {
88
+ out[b * segs + s] = band[s];
89
+ }
90
+ }
91
+ evenCache.set(key, out);
92
+ return out;
93
+ };
94
+ const SPAN = 1.86;
95
+ export const orbPoint = (u, v, phase, p, index, even) => {
96
+ const th = v * TAU + p.shear * phase * 0.55 * (u - 0.5) * 2;
97
+ const wave = p.waveA * Math.sin(th * 3 - phase * 1.7 + u * 3.1) + p.waveB * Math.sin(th * 5 + phase * 1.1);
98
+ const y = Math.max(-0.995, Math.min(0.995, (u - 0.5) * SPAN * p.belt + wave));
99
+ const r = Math.sqrt(Math.max(0, 1 - y * y));
100
+ let point = [r * Math.cos(th), y * p.squash, r * Math.sin(th)];
101
+ if (p.rot) {
102
+ const c = Math.cos(p.rot);
103
+ const s = Math.sin(p.rot);
104
+ point = [point[0], point[1] * c - point[2] * s, point[1] * s + point[2] * c];
105
+ }
106
+ if (p.jitter > 0.001) {
107
+ const e = even[index];
108
+ point = [
109
+ point[0] + (e[0] - point[0]) * p.jitter,
110
+ point[1] + (e[1] - point[1]) * p.jitter,
111
+ point[2] + (e[2] - point[2]) * p.jitter,
112
+ ];
113
+ const len = Math.hypot(point[0], point[1], point[2]) || 1;
114
+ point = [point[0] / len, point[1] / len, point[2] / len];
115
+ }
116
+ return point;
117
+ };
118
+ export const meshFor = (size) => {
119
+ const budget = (size / 64) ** 1.366;
120
+ const axis = Math.sqrt(budget);
121
+ const small = Math.min(1, Math.max(0, (64 - size) / 44));
122
+ return {
123
+ aMin: 0.4 + 0.2 * small,
124
+ ghostAlpha: 0.14,
125
+ ghostAlphaSpan: 0.3,
126
+ ghostCount: Math.max(30, Math.round(80 * budget)),
127
+ ghostRadius: 0.8,
128
+ ghostShade: 0.66,
129
+ lanes: Math.max(4, Math.round(14 * axis)),
130
+ radiusBase: 0.8,
131
+ radiusDepth: 1.35,
132
+ radiusScale: (size / 300) ** 0.6 * 0.85 * (64 / size) ** 0.26,
133
+ segs: Math.max(10, Math.round(78 * axis)),
134
+ shadeFar: 0.6 - 0.16 * small,
135
+ shadeSpan: 0.56 - 0.14 * small,
136
+ };
137
+ };
138
+ const TILT = 0.55;
139
+ const ROLL = 0.3;
140
+ export const project = (size, x, y, z) => {
141
+ const c = size / 2;
142
+ const radius = (size / 2) * 0.78;
143
+ const st = Math.sin(TILT);
144
+ const ct = Math.cos(TILT);
145
+ const sr = Math.sin(ROLL);
146
+ const cr = Math.cos(ROLL);
147
+ const dx = x * cr + z * sr;
148
+ const dz = -x * sr + z * cr;
149
+ return [c + dx * radius, c - (y * ct - dz * st) * radius, y * st + dz * ct];
150
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix",
3
3
  "description": "Styled component tier. Extends the headless tier with token-driven presentation.",
4
- "version": "0.7.2",
4
+ "version": "0.8.0",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -46,14 +46,14 @@
46
46
  },
47
47
  "bugs": "https://github.com/project-fusion/fusion/issues",
48
48
  "dependencies": {
49
- "@fusion.dev/helix-core": "0.7.2",
50
- "@fusion.dev/helix-headless": "0.7.2",
51
- "@fusion.dev/helix-styles": "0.7.2"
49
+ "@fusion.dev/helix-core": "0.8.0",
50
+ "@fusion.dev/helix-headless": "0.8.0",
51
+ "@fusion.dev/helix-styles": "0.8.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@custom-elements-manifest/analyzer": "^0.11.0",
55
- "@fusion.dev/helix-cem": "0.7.2",
56
- "@fusion.dev/helix-testing": "0.7.2",
55
+ "@fusion.dev/helix-cem": "0.8.0",
56
+ "@fusion.dev/helix-testing": "0.8.0",
57
57
  "@fusion.dev/scripts": "0.0.0-dev",
58
58
  "@happy-dom/global-registrator": "^20.0.0",
59
59
  "@lit-labs/ssr": "^3.3.0",
package/types/jsx.d.ts CHANGED
@@ -87,6 +87,7 @@ import type {
87
87
  HelixNumberInput,
88
88
  HelixOption,
89
89
  HelixOptionGroup,
90
+ HelixOrb,
90
91
  HelixOutline,
91
92
  HelixPagination,
92
93
  HelixPaginationSize,
@@ -10578,6 +10579,63 @@ on, which is a change of its own rather than a property being added. */
10578
10579
  textContent?: (string | number) | undefined;
10579
10580
  };
10580
10581
 
10582
+ export type HelixOrbProps = {
10583
+ /** Accessible name, where the state's own word is not the right one.
10584
+
10585
+ Empty is the state's word, which is what most callers want and none of them
10586
+ should have to write. A caller with something better to say says it here:
10587
+ the name of the tool being run, or the file being read. */
10588
+ label?: (HelixOrb["label"]) | undefined;
10589
+ /** Diameter relative to the surrounding text.
10590
+
10591
+ Reflected because the stylesheet selects on it. The mesh is chosen from the
10592
+ rendered box rather than from this, so `--orb-size` and a consumer's own
10593
+ `inline-size` get the same treatment as the three named steps. */
10594
+ size?: (HelixOrb["size"]) | undefined;
10595
+ /** What the agent is doing.
10596
+
10597
+ **A name we do not draw is drawn as `thinking` rather than as nothing.**
10598
+ The set of things an agent can be doing grows faster than this list, and a
10599
+ verb we have not made a shape for should cost a reader a less specific
10600
+ indicator, not an empty box where the indicator was.
10601
+
10602
+ Not reflected: no rule selects on it, because the state is drawn rather than
10603
+ styled. A consumer writing the attribute can still select on their own
10604
+ markup. */
10605
+ state?: (HelixOrb["state"]) | undefined;
10606
+ };
10607
+
10608
+ export type HelixOrbSolidJsProps = {
10609
+ /** Accessible name, where the state's own word is not the right one.
10610
+
10611
+ Empty is the state's word, which is what most callers want and none of them
10612
+ should have to write. A caller with something better to say says it here:
10613
+ the name of the tool being run, or the file being read. */
10614
+ "prop:label"?: (HelixOrb["label"]) | undefined;
10615
+ /** Diameter relative to the surrounding text.
10616
+
10617
+ Reflected because the stylesheet selects on it. The mesh is chosen from the
10618
+ rendered box rather than from this, so `--orb-size` and a consumer's own
10619
+ `inline-size` get the same treatment as the three named steps. */
10620
+ "prop:size"?: (HelixOrb["size"]) | undefined;
10621
+ /** What the agent is doing.
10622
+
10623
+ **A name we do not draw is drawn as `thinking` rather than as nothing.**
10624
+ The set of things an agent can be doing grows faster than this list, and a
10625
+ verb we have not made a shape for should cost a reader a less specific
10626
+ indicator, not an empty box where the indicator was.
10627
+
10628
+ Not reflected: no rule selects on it, because the state is drawn rather than
10629
+ styled. A consumer writing the attribute can still select on their own
10630
+ markup. */
10631
+ "prop:state"?: (HelixOrb["state"]) | undefined;
10632
+
10633
+ /** Set the innerHTML of the element */
10634
+ innerHTML?: (string) | undefined;
10635
+ /** Set the textContent of the element */
10636
+ textContent?: (string | number) | undefined;
10637
+ };
10638
+
10581
10639
  /** `HelixOutline` component event */
10582
10640
  export type HelixOutlineElementEvent<E = Event> = TypedEvent<HelixOutline, E>;
10583
10641
  /** `helix-before-activate` event type */
@@ -26736,6 +26794,88 @@ export type CustomElements = {
26736
26794
  HelixOptionProps & BaseProps<HelixOption> & BaseEvents<HelixOption>
26737
26795
  >;
26738
26796
 
26797
+ /**
26798
+ * A cloud of dots on a sphere, drawn to a canvas, with one shape per state:
26799
+ * `thinking` is a narrow sash with a wave running through it, `fetching` spreads
26800
+ * into a globe with a highlight sweeping pole to pole, `working` flattens and
26801
+ * tilts with its bands shearing past each other, and `done` settles into an even
26802
+ * ball.
26803
+ *
26804
+ * **None of them is a separate drawing.** Each is the same banded sphere given
26805
+ * different numbers, so changing state interpolates the numbers and every frame
26806
+ * in between is a whole shape. A loader that cuts between pictures says the
26807
+ * work restarted; one that carries a shape into the next says it moved on.
26808
+ *
26809
+ * **Nothing spins.** All the movement is inside the shape, which is what makes
26810
+ * it read as thought rather than as a thing being rotated.
26811
+ *
26812
+ * **The palette is read from the tokens**, not given as colors: a dot's ink is
26813
+ * mixed toward the ground by how far away it is, and both ends come from
26814
+ * `--orb-color` and `--orb-ground`. That is what makes depth survive a theme
26815
+ * change without the consumer restating anything.
26816
+ *
26817
+ * **It stops when nobody is looking**, off screen and in a background tab, and
26818
+ * `prefers-reduced-motion` gets one still frame rather than an empty box.
26819
+ *
26820
+ * ## Attributes & Properties
26821
+ *
26822
+ * Component attributes and properties that can be applied to the element or by using JavaScript.
26823
+ *
26824
+ * - `label`: Accessible name, where the state's own word is not the right one.
26825
+ *
26826
+ * Empty is the state's word, which is what most callers want and none of them
26827
+ * should have to write. A caller with something better to say says it here:
26828
+ * the name of the tool being run, or the file being read.
26829
+ * - `size`: Diameter relative to the surrounding text.
26830
+ *
26831
+ * Reflected because the stylesheet selects on it. The mesh is chosen from the
26832
+ * rendered box rather than from this, so `--orb-size` and a consumer's own
26833
+ * `inline-size` get the same treatment as the three named steps.
26834
+ * - `state`: What the agent is doing.
26835
+ *
26836
+ * **A name we do not draw is drawn as `thinking` rather than as nothing.**
26837
+ * The set of things an agent can be doing grows faster than this list, and a
26838
+ * verb we have not made a shape for should cost a reader a less specific
26839
+ * indicator, not an empty box where the indicator was.
26840
+ *
26841
+ * Not reflected: no rule selects on it, because the state is drawn rather than
26842
+ * styled. A consumer writing the attribute can still select on their own
26843
+ * markup.
26844
+ * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
26845
+ *
26846
+ * **Named `whenSettled` because `settled` is taken four times over**, by
26847
+ * Image, Splitter and both color controls, none of them about transitions. A
26848
+ * base class takes the name every subclass then cannot use.
26849
+ *
26850
+ * **The state it reports cannot be watched, which is why this exists.** A
26851
+ * custom state is deliberately not in the DOM, so there is no
26852
+ * `MutationObserver` equivalent for `ElementInternals.states`. Await this
26853
+ * instead.
26854
+ *
26855
+ * Separate from `updateComplete`, which resolves in the microtask checkpoint
26856
+ * the suppression is still active in. That is the distinction `readyToMove`
26857
+ * in `@fusion.dev/helix-testing` is written around.
26858
+ *
26859
+ * It never resolves where `requestAnimationFrame` never fires, which is a
26860
+ * server, a hidden tab, and happy-dom. Callers that must not hang race it
26861
+ * against a timeout; `readyToMove` does exactly that. (property only) (readonly)
26862
+ *
26863
+ * ## CSS Custom Properties
26864
+ *
26865
+ * CSS variables available for styling the component.
26866
+ *
26867
+ * - `--orb-color`: Ink of the nearest dots. Defaults to `currentColor`. (default: `undefined`)
26868
+ * - `--orb-ground`: What the far dots are mixed toward. Defaults to the page's background. (default: `undefined`)
26869
+ * - `--orb-size`: Diameter. Overrides `size`. (default: `undefined`)
26870
+ *
26871
+ * ## CSS Parts
26872
+ *
26873
+ * Custom selectors for styling elements within the component.
26874
+ *
26875
+ * - `canvas`: The surface the cloud is drawn into.
26876
+ */
26877
+ "helix-orb": Partial<HelixOrbProps & BaseProps<HelixOrb> & BaseEvents<HelixOrb>>;
26878
+
26739
26879
  /**
26740
26880
  * A rule down the leading edge with the current section lit along it, which is
26741
26881
  * the shape a table of contents has taken since printed marginalia: the line
@@ -42553,6 +42693,90 @@ export type CustomElementsSolidJs = {
42553
42693
  BaseEvents<HelixOption>
42554
42694
  >;
42555
42695
 
42696
+ /**
42697
+ * A cloud of dots on a sphere, drawn to a canvas, with one shape per state:
42698
+ * `thinking` is a narrow sash with a wave running through it, `fetching` spreads
42699
+ * into a globe with a highlight sweeping pole to pole, `working` flattens and
42700
+ * tilts with its bands shearing past each other, and `done` settles into an even
42701
+ * ball.
42702
+ *
42703
+ * **None of them is a separate drawing.** Each is the same banded sphere given
42704
+ * different numbers, so changing state interpolates the numbers and every frame
42705
+ * in between is a whole shape. A loader that cuts between pictures says the
42706
+ * work restarted; one that carries a shape into the next says it moved on.
42707
+ *
42708
+ * **Nothing spins.** All the movement is inside the shape, which is what makes
42709
+ * it read as thought rather than as a thing being rotated.
42710
+ *
42711
+ * **The palette is read from the tokens**, not given as colors: a dot's ink is
42712
+ * mixed toward the ground by how far away it is, and both ends come from
42713
+ * `--orb-color` and `--orb-ground`. That is what makes depth survive a theme
42714
+ * change without the consumer restating anything.
42715
+ *
42716
+ * **It stops when nobody is looking**, off screen and in a background tab, and
42717
+ * `prefers-reduced-motion` gets one still frame rather than an empty box.
42718
+ *
42719
+ * ## Attributes & Properties
42720
+ *
42721
+ * Component attributes and properties that can be applied to the element or by using JavaScript.
42722
+ *
42723
+ * - `label`: Accessible name, where the state's own word is not the right one.
42724
+ *
42725
+ * Empty is the state's word, which is what most callers want and none of them
42726
+ * should have to write. A caller with something better to say says it here:
42727
+ * the name of the tool being run, or the file being read.
42728
+ * - `size`: Diameter relative to the surrounding text.
42729
+ *
42730
+ * Reflected because the stylesheet selects on it. The mesh is chosen from the
42731
+ * rendered box rather than from this, so `--orb-size` and a consumer's own
42732
+ * `inline-size` get the same treatment as the three named steps.
42733
+ * - `state`: What the agent is doing.
42734
+ *
42735
+ * **A name we do not draw is drawn as `thinking` rather than as nothing.**
42736
+ * The set of things an agent can be doing grows faster than this list, and a
42737
+ * verb we have not made a shape for should cost a reader a less specific
42738
+ * indicator, not an empty box where the indicator was.
42739
+ *
42740
+ * Not reflected: no rule selects on it, because the state is drawn rather than
42741
+ * styled. A consumer writing the attribute can still select on their own
42742
+ * markup.
42743
+ * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
42744
+ *
42745
+ * **Named `whenSettled` because `settled` is taken four times over**, by
42746
+ * Image, Splitter and both color controls, none of them about transitions. A
42747
+ * base class takes the name every subclass then cannot use.
42748
+ *
42749
+ * **The state it reports cannot be watched, which is why this exists.** A
42750
+ * custom state is deliberately not in the DOM, so there is no
42751
+ * `MutationObserver` equivalent for `ElementInternals.states`. Await this
42752
+ * instead.
42753
+ *
42754
+ * Separate from `updateComplete`, which resolves in the microtask checkpoint
42755
+ * the suppression is still active in. That is the distinction `readyToMove`
42756
+ * in `@fusion.dev/helix-testing` is written around.
42757
+ *
42758
+ * It never resolves where `requestAnimationFrame` never fires, which is a
42759
+ * server, a hidden tab, and happy-dom. Callers that must not hang race it
42760
+ * against a timeout; `readyToMove` does exactly that. (property only) (readonly)
42761
+ *
42762
+ * ## CSS Custom Properties
42763
+ *
42764
+ * CSS variables available for styling the component.
42765
+ *
42766
+ * - `--orb-color`: Ink of the nearest dots. Defaults to `currentColor`. (default: `undefined`)
42767
+ * - `--orb-ground`: What the far dots are mixed toward. Defaults to the page's background. (default: `undefined`)
42768
+ * - `--orb-size`: Diameter. Overrides `size`. (default: `undefined`)
42769
+ *
42770
+ * ## CSS Parts
42771
+ *
42772
+ * Custom selectors for styling elements within the component.
42773
+ *
42774
+ * - `canvas`: The surface the cloud is drawn into.
42775
+ */
42776
+ "helix-orb": Partial<
42777
+ HelixOrbProps & HelixOrbSolidJsProps & BaseProps<HelixOrb> & BaseEvents<HelixOrb>
42778
+ >;
42779
+
42556
42780
  /**
42557
42781
  * A rule down the leading edge with the current section lit along it, which is
42558
42782
  * the shape a table of contents has taken since printed marginalia: the line
@@ -50169,6 +50393,12 @@ export type CustomCssProperties = {
50169
50393
  "--option-padding"?: (string) | undefined;
50170
50394
  /** Corner radius of the row. A listbox and a select flatten it. */
50171
50395
  "--option-radius"?: (string) | undefined;
50396
+ /** Ink of the nearest dots. Defaults to `currentColor`. */
50397
+ "--orb-color"?: (string) | undefined;
50398
+ /** What the far dots are mixed toward. Defaults to the page's background. */
50399
+ "--orb-ground"?: (string) | undefined;
50400
+ /** Diameter. Overrides `size`. */
50401
+ "--orb-size"?: (string) | undefined;
50172
50402
  /** How far each level is inset from the one above. */
50173
50403
  "--outline-indent"?: (string) | undefined;
50174
50404
  /** Width of the gutter the rule and the traveling mark share. */
package/types/svelte.d.ts CHANGED
@@ -72,6 +72,7 @@ declare module 'svelte/elements' {
72
72
  'helix-number-input': CustomElements['helix-number-input']
73
73
  'helix-option-group': CustomElements['helix-option-group']
74
74
  'helix-option': CustomElements['helix-option']
75
+ 'helix-orb': CustomElements['helix-orb']
75
76
  'helix-outline': CustomElements['helix-outline']
76
77
  'helix-pagination': CustomElements['helix-pagination']
77
78
  'helix-pagination-size': CustomElements['helix-pagination-size']
package/types/vue.d.ts CHANGED
@@ -64,6 +64,7 @@ import type {
64
64
  HelixNumberInput,
65
65
  HelixOptionGroup,
66
66
  HelixOption,
67
+ HelixOrb,
67
68
  HelixOutline,
68
69
  HelixPagination,
69
70
  HelixPaginationSize,
@@ -5403,6 +5404,34 @@ export type HelixOptionVueEvents = {
5403
5404
  "helix-select": HelixOptionHelixSelectElementEvent;
5404
5405
  };
5405
5406
 
5407
+ export type HelixOrbVueProps = {
5408
+ /** Accessible name, where the state's own word is not the right one.
5409
+
5410
+ Empty is the state's word, which is what most callers want and none of them
5411
+ should have to write. A caller with something better to say says it here:
5412
+ the name of the tool being run, or the file being read. */
5413
+ label?: (HelixOrb["label"]) | undefined;
5414
+ /** Diameter relative to the surrounding text.
5415
+
5416
+ Reflected because the stylesheet selects on it. The mesh is chosen from the
5417
+ rendered box rather than from this, so `--orb-size` and a consumer's own
5418
+ `inline-size` get the same treatment as the three named steps. */
5419
+ size?: (HelixOrb["size"]) | undefined;
5420
+ /** What the agent is doing.
5421
+
5422
+ **A name we do not draw is drawn as `thinking` rather than as nothing.**
5423
+ The set of things an agent can be doing grows faster than this list, and a
5424
+ verb we have not made a shape for should cost a reader a less specific
5425
+ indicator, not an empty box where the indicator was.
5426
+
5427
+ Not reflected: no rule selects on it, because the state is drawn rather than
5428
+ styled. A consumer writing the attribute can still select on their own
5429
+ markup. */
5430
+ state?: (HelixOrb["state"]) | undefined;
5431
+ };
5432
+
5433
+ export type HelixOrbVueEvents = {};
5434
+
5406
5435
  /** `HelixOutline` component event */
5407
5436
  export type HelixOutlineElementEvent<E = Event> = TypedEvent<HelixOutline, E>;
5408
5437
  /** `helix-before-activate` event type */
@@ -9755,6 +9784,12 @@ export type CustomCssProperties = {
9755
9784
  "--option-padding"?: (string) | undefined;
9756
9785
  /** Corner radius of the row. A listbox and a select flatten it. */
9757
9786
  "--option-radius"?: (string) | undefined;
9787
+ /** Ink of the nearest dots. Defaults to `currentColor`. */
9788
+ "--orb-color"?: (string) | undefined;
9789
+ /** What the far dots are mixed toward. Defaults to the page's background. */
9790
+ "--orb-ground"?: (string) | undefined;
9791
+ /** Diameter. Overrides `size`. */
9792
+ "--orb-size"?: (string) | undefined;
9758
9793
  /** How far each level is inset from the one above. */
9759
9794
  "--outline-indent"?: (string) | undefined;
9760
9795
  /** Width of the gutter the rule and the traveling mark share. */
@@ -10517,6 +10552,12 @@ export interface WcToolkitVueGlobalComponents {
10517
10552
  HelixOptionVueProps,
10518
10553
  HelixOptionVueEvents
10519
10554
  >;
10555
+ /** A cloud of dots on a sphere, drawn to a canvas, with one shape per state: 'thinking' is a narrow sash with a wave running through it, 'fetching' spreads into a globe with a highlight sweeping pole to pole, 'working' flattens and tilts with its bands shearing past each other, and 'done' settles into an even ball. **None of them is a separate drawing.** Each is the same banded sphere given different numbers, so changing state interpolates the numbers and every frame in between is a whole shape. A loader that cuts between pictures says the work restarted; one that carries a shape into the next says it moved on. **Nothing spins.** All the movement is inside the shape, which is what makes it read as thought rather than as a thing being rotated. **The palette is read from the tokens**, not given as colors: a dot's ink is mixed toward the ground by how far away it is, and both ends come from '--orb-color' and '--orb-ground'. That is what makes depth survive a theme change without the consumer restating anything. **It stops when nobody is looking**, off screen and in a background tab, and 'prefers-reduced-motion' gets one still frame rather than an empty box. */
10556
+ "helix-orb": DefineCustomElement<
10557
+ HelixOrb,
10558
+ HelixOrbVueProps,
10559
+ HelixOrbVueEvents
10560
+ >;
10520
10561
  /** A rule down the leading edge with the current section lit along it, which is the shape a table of contents has taken since printed marginalia: the line says the list is one thing, and the lit segment says where in it you are. Nesting is the consumer's, expressed as 'data-level' on a link. An outline that read heading levels itself would have to look at the document, and the document is not always where the headings are. */
10521
10562
  "helix-outline": DefineCustomElement<
10522
10563
  HelixOutline,