weasel-icons 0.7.0 → 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.
Files changed (49) hide show
  1. package/README.md +9 -1
  2. package/THIRD_PARTY_NOTICES.md +2 -0
  3. package/dist/icons/badge-percent/badge-percent-icon.d.ts +5 -0
  4. package/dist/icons/badge-percent/badge-percent-icon.js +9 -0
  5. package/dist/icons/badge-percent/badge-percent-rig.d.ts +4 -0
  6. package/dist/icons/badge-percent/badge-percent-rig.js +63 -0
  7. package/dist/icons/blocks/blocks-icon.d.ts +5 -0
  8. package/dist/icons/blocks/blocks-icon.js +9 -0
  9. package/dist/icons/blocks/blocks-rig.d.ts +4 -0
  10. package/dist/icons/blocks/blocks-rig.js +34 -0
  11. package/dist/icons/bot/bot-icon.d.ts +5 -0
  12. package/dist/icons/bot/bot-icon.js +9 -0
  13. package/dist/icons/bot/bot-rig.d.ts +4 -0
  14. package/dist/icons/bot/bot-rig.js +79 -0
  15. package/dist/icons/brick-wall/brick-wall-icon.d.ts +5 -0
  16. package/dist/icons/brick-wall/brick-wall-icon.js +9 -0
  17. package/dist/icons/brick-wall/brick-wall-rig.d.ts +4 -0
  18. package/dist/icons/brick-wall/brick-wall-rig.js +55 -0
  19. package/dist/icons/dice/dice-icon.d.ts +5 -0
  20. package/dist/icons/dice/dice-icon.js +9 -0
  21. package/dist/icons/dice/dice-rig.d.ts +158 -0
  22. package/dist/icons/dice/dice-rig.js +96 -0
  23. package/dist/icons/dog/dog-icon.js +1 -4
  24. package/dist/icons/dog/dog-rig.d.ts +1 -13
  25. package/dist/icons/dog/dog-rig.js +39 -159
  26. package/dist/icons/footprints/footprints-icon.d.ts +5 -0
  27. package/dist/icons/footprints/footprints-icon.js +9 -0
  28. package/dist/icons/footprints/footprints-rig.d.ts +4 -0
  29. package/dist/icons/footprints/footprints-rig.js +53 -0
  30. package/dist/icons/fuel/fuel-icon.d.ts +5 -0
  31. package/dist/icons/fuel/fuel-icon.js +9 -0
  32. package/dist/icons/fuel/fuel-rig.d.ts +4 -0
  33. package/dist/icons/fuel/fuel-rig.js +55 -0
  34. package/dist/icons/infinity/infinity-icon.d.ts +5 -0
  35. package/dist/icons/infinity/infinity-icon.js +17 -0
  36. package/dist/icons/infinity/infinity-rig.d.ts +3 -0
  37. package/dist/icons/infinity/infinity-rig.js +4 -0
  38. package/dist/icons/target/target-icon.d.ts +5 -0
  39. package/dist/icons/target/target-icon.js +9 -0
  40. package/dist/icons/target/target-rig.d.ts +112 -0
  41. package/dist/icons/target/target-rig.js +81 -0
  42. package/dist/icons/webhook/webhook-icon.d.ts +5 -0
  43. package/dist/icons/webhook/webhook-icon.js +74 -0
  44. package/dist/icons/webhook/webhook-rig.d.ts +10 -0
  45. package/dist/icons/webhook/webhook-rig.js +50 -0
  46. package/dist/index.d.ts +10 -0
  47. package/dist/index.js +10 -0
  48. package/dist/shared/icon-colors.d.ts +10 -0
  49. package/package.json +51 -1
@@ -31,9 +31,6 @@ export const DogIcon = memo(function DogIcon({ state = 'waiting', size = 24, col
31
31
  const tongueHeight = useTransform(rig, (r) => r.tongueHeight);
32
32
  const tongueOpacity = useTransform(rig, (r) => r.tongueOpacity);
33
33
  const blush = useTransform(rig, (r) => r.blush);
34
- const scentPath = useTransform(rig, (r) => `M ${r.scentX} ${r.scentY - 0.7} q -.7 -.3 -1.15 .05 M ${r.scentX + 0.2} ${r.scentY + 0.75} q -.7 .3 -1.15 -.05`);
35
- const scentOpacity = useTransform(rig, (r) => r.scentOpacity);
36
- const sparkOpacity = useTransform(rig, (r) => r.sparkOpacity);
37
34
  const tilt = useTransform(rig, (r) => r.tilt);
38
35
  const height = useTransform(rig, (r) => r.headY);
39
36
  const headTilt = useFollowPose(tilt, pace, reduced);
@@ -41,5 +38,5 @@ export const DogIcon = memo(function DogIcon({ state = 'waiting', size = 24, col
41
38
  const head = useTransform(() => `translate(12px, ${14 + headY.get()}px) rotate(${headTilt.get()}deg) translate(-12px, -14px)`);
42
39
  const detailStroke = Math.max(0.35, strokeWidth * 0.38);
43
40
  const surface = 'var(--weasel-surface, #fff)';
44
- return (_jsxs("svg", { ref: element, className: className, width: size, height: size, viewBox: "-3 -3 30 30", xmlns: "http://www.w3.org/2000/svg", fill: "none", preserveAspectRatio: "xMidYMid meet", "aria-hidden": "true", focusable: "false", pointerEvents: "none", "data-dog-state": state, style: { display: 'block', overflow: 'visible' }, children: [_jsx("defs", { children: _jsx("clipPath", { id: mouthId, children: _jsx(motion.path, { d: mouth }) }) }), _jsxs(motion.g, { "data-layer": "face", style: SVG_ORIGIN, transform: head, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: DOG_SURFACE, fill: surface }), _jsx("path", { d: DOG_OUTLINE, stroke: color, strokeWidth: strokeWidth }), _jsx("path", { d: "M10.15 5.235Q12 4.6 14 5.277", stroke: color, strokeWidth: strokeWidth }), _jsx(motion.path, { "data-layer": "left-ear", style: SVG_ORIGIN, d: DOG_LEFT_EAR, transform: leftEar, stroke: color, fill: surface, strokeWidth: strokeWidth }), _jsx(motion.path, { "data-layer": "right-ear", style: SVG_ORIGIN, d: DOG_RIGHT_EAR, transform: rightEar, stroke: color, fill: surface, strokeWidth: strokeWidth }), _jsxs(motion.g, { "data-layer": "cheeks", opacity: blush, fill: accentColor, children: [_jsx("ellipse", { cx: "7.1", cy: "16.3", rx: ".8", ry: ".38" }), _jsx("ellipse", { cx: "16.9", cy: "16.3", rx: ".8", ry: ".38" })] }), _jsx(motion.path, { "data-layer": "left-eye", d: leftEye, fill: colors?.eyes ?? color }), _jsx(motion.path, { "data-layer": "right-eye", d: rightEye, fill: colors?.eyes ?? color }), _jsx(motion.path, { "data-layer": "nose", d: "M11.1 15.9Q12 15.55 12.9 15.9Q13.2 16.2 12 17Q10.8 16.2 11.1 15.9Z", style: SVG_ORIGIN, transform: nose, fill: colors?.nose ?? color }), _jsx(motion.path, { "data-layer": "mouth", d: mouth, fill: colors?.mouth ?? color, stroke: colors?.mouth ?? color, strokeWidth: detailStroke }), _jsx("g", { clipPath: `url(#${mouthId})`, children: _jsx(motion.rect, { "data-layer": "tongue", x: "11.2", y: tongueY, width: "1.6", height: tongueHeight, rx: ".65", opacity: tongueOpacity, fill: accentColor }) })] }), _jsx(motion.g, { "data-layer": "scent", opacity: scentOpacity, stroke: accentColor, strokeWidth: detailStroke, strokeLinecap: "round", children: _jsx(motion.path, { d: scentPath }) }), _jsx(motion.path, { "data-layer": "spark", opacity: sparkOpacity, d: "M.1 1.3v2M-.9 2.3h2M24.1 .5v1.4M23.4 1.2h1.4", stroke: accentColor, strokeWidth: detailStroke, strokeLinecap: "round" })] }));
41
+ return (_jsxs("svg", { ref: element, className: className, width: size, height: size, viewBox: "-3 -3 30 30", xmlns: "http://www.w3.org/2000/svg", fill: "none", preserveAspectRatio: "xMidYMid meet", "aria-hidden": "true", focusable: "false", pointerEvents: "none", "data-dog-state": state, style: { display: 'block', overflow: 'visible' }, children: [_jsx("defs", { children: _jsx("clipPath", { id: mouthId, children: _jsx(motion.path, { d: mouth }) }) }), _jsxs(motion.g, { "data-layer": "face", style: SVG_ORIGIN, transform: head, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: DOG_SURFACE, fill: surface }), _jsx("path", { d: DOG_OUTLINE, stroke: color, strokeWidth: strokeWidth }), _jsx("path", { d: "M10.15 5.235Q12 4.6 14 5.277", stroke: color, strokeWidth: strokeWidth }), _jsx(motion.path, { "data-layer": "left-ear", style: SVG_ORIGIN, d: DOG_LEFT_EAR, transform: leftEar, stroke: color, fill: surface, strokeWidth: strokeWidth }), _jsx(motion.path, { "data-layer": "right-ear", style: SVG_ORIGIN, d: DOG_RIGHT_EAR, transform: rightEar, stroke: color, fill: surface, strokeWidth: strokeWidth }), _jsxs(motion.g, { "data-layer": "cheeks", opacity: blush, fill: accentColor, children: [_jsx("ellipse", { cx: "7.1", cy: "16.3", rx: ".8", ry: ".38" }), _jsx("ellipse", { cx: "16.9", cy: "16.3", rx: ".8", ry: ".38" })] }), _jsx(motion.path, { "data-layer": "left-eye", d: leftEye, fill: colors?.eyes ?? color }), _jsx(motion.path, { "data-layer": "right-eye", d: rightEye, fill: colors?.eyes ?? color }), _jsx(motion.path, { "data-layer": "nose", d: "M11.1 15.9Q12 15.55 12.9 15.9Q13.2 16.2 12 17Q10.8 16.2 11.1 15.9Z", style: SVG_ORIGIN, transform: nose, fill: colors?.nose ?? color }), _jsx(motion.path, { "data-layer": "mouth", d: mouth, fill: colors?.mouth ?? color, stroke: colors?.mouth ?? color, strokeWidth: detailStroke }), _jsx("g", { clipPath: `url(#${mouthId})`, children: _jsx(motion.rect, { "data-layer": "tongue", x: "11.2", y: tongueY, width: "1.6", height: tongueHeight, rx: ".65", opacity: tongueOpacity, fill: accentColor }) })] })] }));
45
42
  });
@@ -24,14 +24,10 @@ interface DogPose {
24
24
  noseY: number;
25
25
  tongue: number;
26
26
  blush: number;
27
- scent: number;
28
- scentX: number;
29
- scentY: number;
30
- spark: number;
31
27
  }
32
28
  export declare const DOG_POSES: Record<DogState, DogPose>;
33
29
  export declare const dogBehaviors: Record<DogState, readonly string[]>;
34
- export declare const dogSceneDuration: (state: DogState) => 6 | 8;
30
+ export declare const dogSceneDuration: (state: DogState) => 3.8 | 4.8 | 6.8;
35
31
  export declare function sampleDogBehavior(state: DogState, time: number): {
36
32
  pose: {
37
33
  gazeX: number;
@@ -52,10 +48,6 @@ export declare function sampleDogBehavior(state: DogState, time: number): {
52
48
  noseY: number;
53
49
  tongue: number;
54
50
  blush: number;
55
- scent: number;
56
- scentX: number;
57
- scentY: number;
58
- spark: number;
59
51
  };
60
52
  scene: number;
61
53
  };
@@ -72,9 +64,5 @@ export declare function sampleDog(weights: DogWeights, time?: number, alive?: nu
72
64
  tongueHeight: number;
73
65
  tongueOpacity: number;
74
66
  blush: number;
75
- scentX: number;
76
- scentY: number;
77
- scentOpacity: number;
78
- sparkOpacity: number;
79
67
  };
80
68
  export {};
@@ -24,10 +24,6 @@ const neutral = {
24
24
  noseY: 0,
25
25
  tongue: 0,
26
26
  blush: 0,
27
- scent: 0,
28
- scentX: 24,
29
- scentY: 8,
30
- spark: 0,
31
27
  };
32
28
  export const DOG_POSES = {
33
29
  waiting: neutral,
@@ -76,170 +72,58 @@ export const DOG_POSES = {
76
72
  headY: 0.32,
77
73
  },
78
74
  };
75
+ // One restrained gesture per state. The settled expressions and accepted drawing stay unchanged.
76
+ // waiting: an attentive glance leads a small head tilt, then a quiet blink.
77
+ // sniffing: two short nose-led inhalations; the head follows without extra scent marks.
78
+ // happy: a low-amplitude pant supports the held smile; ears stay composed.
79
+ // guilty: a brief upward peek returns to the lowered gaze. It never acts as if the error cleared.
79
80
  export const dogBehaviors = {
80
- waiting: ['did you call?', 'patient little blink', 'checking on you', 'tiny nose twitch'],
81
- sniffing: ['catch the scent', 'double sniff', 'where did it go?', 'one more clue'],
82
- happy: ['soft little pant', 'good puppy nod', 'ear-flop delight', 'bashful little grin'],
83
- guilty: [
84
- 'look away, peek back',
85
- 'ears down, little sigh',
86
- 'is it okay now?',
87
- 'ready to try again',
88
- ],
81
+ waiting: ['quiet attentive glance'],
82
+ sniffing: ['gentle double sniff'],
83
+ happy: ['soft pant and smile'],
84
+ guilty: ['small apologetic peek'],
89
85
  };
90
- export const dogSceneDuration = (state) => state === 'happy' || state === 'sniffing' ? 6 : 8;
86
+ export const dogSceneDuration = (state) => state === 'sniffing' ? 3.8 : state === 'happy' ? 4.8 : 6.8;
91
87
  export function sampleDogBehavior(state, time) {
92
- const duration = dogSceneDuration(state);
93
- const slot = Math.floor(Math.max(0, time) / duration);
94
- const phrase = Math.floor(slot / 4);
95
- const scene = ((phrase % 2 ? 3 - (slot % 4) : slot % 4) + phrase) % 4;
96
- const delay = 0.35 + ((slot * 7 + dogStates.indexOf(state) * 3) % 9) * 0.045;
97
- const t = time - slot * duration - delay;
98
- const beat = (start, rise = 0.55, hold = 0.7, fall = 0.9) => behaviorBeat(t, start, rise, hold, fall);
88
+ const period = dogSceneDuration(state);
89
+ const t = ((time % period) + period) % period;
90
+ const beat = (start, rise, hold, fall) => behaviorBeat(t, start, rise, hold, fall);
99
91
  const p = { ...DOG_POSES[state] };
100
- const a = beat(0.15), b = beat(2.8, 0.4, 0.55, 0.9);
101
92
  if (state === 'waiting') {
102
- if (scene === 0) {
103
- p.gazeX += a * 0.6;
104
- p.earRight += beat(0.35) * 7;
105
- p.tilt -= beat(0.45, 0.65, 0.7, 1) * 4;
106
- }
107
- else if (scene === 1) {
108
- p.eyeOpen *= 1 - beat(0.4, 0.65, 0.15, 0.8) * 0.8;
109
- p.headY += a * 0.16;
110
- p.mouthWidth += b * 0.3;
111
- }
112
- else if (scene === 2) {
113
- p.gazeX -= a * 0.5;
114
- p.gazeY += a * 0.15;
115
- p.tilt += beat(0.4) * 2.5;
116
- p.gazeX += b * 0.45;
117
- p.earLeft -= b * 3;
118
- }
119
- else {
120
- const sniff = beat(0.35, 0.18, 0.05, 0.35) + beat(1.1, 0.2, 0.05, 0.4) * 0.65;
121
- p.nose += sniff * 0.12;
122
- p.headY -= sniff * 0.07;
123
- p.tilt -= b * 1.5;
124
- }
93
+ const glance = beat(0.4, 0.5, 0.55, 0.8);
94
+ p.gazeX += glance * 0.28;
95
+ p.tilt -= beat(0.58, 0.65, 0.45, 0.95) * 2;
96
+ p.earRight += beat(0.76, 0.45, 0.3, 0.8) * 1.5;
125
97
  }
126
98
  else if (state === 'sniffing') {
127
- // Nose acquires the scent before the head follows. Short inhalations,
128
- // not a continuously inflating nose or an entire shaking face.
129
- const inhale = beat(0.65, 0.12, 0.04, 0.23) +
130
- beat(1.12, 0.14, 0.03, 0.26) * 0.8 +
131
- beat(2.75, 0.14, 0.04, 0.3) * 0.65;
132
- const seek = beat(0.08, 0.55, 1.3, 0.75);
133
- p.nose += inhale * 0.045;
134
- p.noseY -= inhale * 0.15;
135
- p.eyeOpen *= 1 - inhale * 0.13;
136
- p.headY -= beat(0.78, 0.18, 0.04, 0.36) * 0.12;
137
- if (scene === 0) {
138
- p.gazeX += seek * 0.38;
139
- p.gazeY -= seek * 0.16;
140
- p.noseX += seek * 0.15;
141
- p.tilt -= beat(0.32, 0.65, 1.05, 0.85) * 2.4;
142
- p.earRight += beat(0.5, 0.4, 0.4, 0.9) * 2;
143
- }
144
- else if (scene === 1) {
145
- p.gazeY += seek * 0.3;
146
- p.noseY += seek * 0.1;
147
- p.headY += beat(0.35, 0.6, 0.8, 0.8) * 0.28;
148
- p.earLeft -= beat(0.7, 0.3, 0.1, 0.65) * 2.4;
149
- p.mouthWidth -= inhale * 0.15;
150
- }
151
- else if (scene === 2) {
152
- p.gazeX -= seek * 0.9;
153
- p.noseX -= seek * 0.27;
154
- p.tilt += beat(0.4, 0.7, 0.8, 0.9) * 5;
155
- p.earLeft -= beat(0.6, 0.4, 0.5, 0.8) * 2;
156
- p.gazeX += b * 0.2;
157
- }
158
- else {
159
- p.gazeY -= seek * 0.35;
160
- p.noseY -= seek * 0.12;
161
- p.headY -= beat(0.4, 0.7, 0.7, 0.9) * 0.22;
162
- p.earRight += beat(0.55, 0.4, 0.5, 0.8) * 2.2;
163
- p.tilt += b * 1.5;
164
- }
165
- // Two brief scent wisps stay outside the cheek; they aren't facial dots.
166
- p.scent = inhale * 0.65;
167
- p.scentX = 23.2 - inhale * 0.65;
168
- p.scentY = 15.2 - seek * 0.25;
99
+ const first = beat(0.42, 0.14, 0.04, 0.28);
100
+ const second = beat(0.96, 0.14, 0.04, 0.32) * 0.75;
101
+ const inhale = first + second;
102
+ p.noseY -= inhale * 0.16;
103
+ p.nose += inhale * 0.018;
104
+ p.eyeOpen *= 1 - inhale * 0.12;
105
+ // Follow the same two inhalations slightly later; never shake the whole face.
106
+ p.headY -= (beat(0.52, 0.18, 0.02, 0.34) + beat(1.06, 0.18, 0.02, 0.38) * 0.75) * 0.2;
107
+ p.gazeX += beat(0.18, 0.4, 0.8, 0.8) * 0.16;
108
+ p.tilt -= beat(0.32, 0.55, 0.55, 0.9) * 1.4;
169
109
  }
170
110
  else if (state === 'happy') {
171
- // Low-amplitude jaw/tongue rhythm has an independent phase, so it never
172
- // restarts at a phrase boundary. The silhouette itself stays composed.
173
- const pant = 0.5 - 0.5 * Math.cos((time * Math.PI * 2) / 1.65);
174
- p.bottom += pant * 0.18;
175
- p.tongue += pant * 0.075;
176
- if (scene === 0) {
177
- p.eyeOpen -= a * 0.25;
178
- p.eyeCurve -= a * 0.12;
179
- p.tilt -= beat(0.4, 0.65, 0.35, 0.85) * 2;
180
- p.earLeft -= beat(0.55, 0.4, 0.12, 0.75) * 2.5;
181
- }
182
- else if (scene === 1) {
183
- const nod = beat(0.5, 0.3, 0.06, 0.65);
184
- p.headY += nod * 0.3;
185
- p.earLeft -= beat(0.68, 0.25, 0.05, 0.7) * 3;
186
- p.earRight += beat(0.76, 0.25, 0.05, 0.7) * 3;
187
- p.eyeOpen -= nod * 0.22;
188
- }
189
- else if (scene === 2) {
190
- p.tilt += beat(0.2, 0.55, 0.2, 0.8) * 2;
191
- p.earLeft -= beat(0.38, 0.3, 0.08, 0.65) * 3.5;
192
- p.earRight += beat(0.55, 0.3, 0.08, 0.7) * 3;
193
- p.eyeOpen -= b * 0.35;
194
- p.eyeCurve -= b * 0.12;
195
- }
196
- else {
197
- p.gazeX -= a * 0.25;
198
- p.bottom -= a * 0.25;
199
- p.tongue -= a * 0.15;
200
- p.tilt -= beat(0.35, 0.6, 0.4, 0.9) * 2.5;
201
- p.eyeOpen -= a * 0.35;
202
- p.eyeCurve -= a * 0.16;
203
- p.blush += a * 0.05;
204
- }
111
+ // An independent phase keeps the soft jaw/tongue motion continuous across gesture boundaries.
112
+ const pant = 0.5 - 0.5 * Math.cos((time * Math.PI * 2) / 2.4);
113
+ p.bottom += pant * 0.1;
114
+ p.tongue += pant * 0.045;
115
+ p.eyeOpen -= beat(0.55, 0.45, 0.2, 0.65) * 0.12;
205
116
  }
206
117
  else {
207
- if (scene === 0) {
208
- p.gazeX -= a * 0.55;
209
- p.gazeX += b * 0.6;
210
- p.gazeY -= b * 0.24;
211
- p.tilt += beat(0.5) * 1.3;
212
- p.earLeft += a * 3;
213
- }
214
- else if (scene === 1) {
215
- const sigh = beat(0.35, 0.8, 0.35, 1.2);
216
- p.eyeOpen *= 1 - sigh * 0.6;
217
- p.headY += sigh * 0.2;
218
- p.mouthWidth -= sigh * 1.1;
219
- p.bottom += sigh * 0.4;
220
- p.earLeft += sigh * 2;
221
- p.earRight -= sigh * 2;
222
- }
223
- else if (scene === 2) {
224
- p.gazeY -= a * 0.45;
225
- p.eyeOpen += a * 0.2;
226
- p.tilt -= beat(0.45) * 2.5;
227
- p.earRight += a * 4;
228
- p.mouthWidth += b * 0.25;
229
- }
230
- else {
231
- p.gazeX += a * 0.3;
232
- p.gazeY -= a * 0.3;
233
- p.headY -= beat(0.5) * 0.23;
234
- p.earLeft -= a * 3;
235
- p.earRight += a * 3;
236
- p.tilt -= a * 2;
237
- p.eyeOpen += b * 0.13;
238
- }
118
+ const peek = beat(1, 0.55, 0.4, 0.95);
119
+ p.gazeY -= peek * 0.22;
120
+ p.gazeX += peek * 0.18;
121
+ p.tilt -= beat(1.18, 0.65, 0.25, 0.95) * 0.8;
239
122
  }
240
- const blink = Math.max(gesture(time, 10.7, 2.3, 0.27), gesture(time, 17.3, 6.9, 0.3));
123
+ // A short blink replaces the old slow eye squeezes. It shares the single eye-path owner.
124
+ const blink = gesture(time, period, state === 'sniffing' ? 2.9 : 3.6, 0.24);
241
125
  p.eyeOpen *= 1 - blink * 0.88;
242
- return { pose: p, scene };
126
+ return { pose: p, scene: 0 };
243
127
  }
244
128
  const keys = Object.keys(neutral);
245
129
  const n = (value) => Number(value.toFixed(4));
@@ -277,9 +161,5 @@ export function sampleDog(weights, time = 0, alive = 0) {
277
161
  tongueHeight: 0.18 + p.tongue * 1.35,
278
162
  tongueOpacity: p.tongue,
279
163
  blush: p.blush,
280
- scentX: p.scentX,
281
- scentY: p.scentY,
282
- scentOpacity: p.scent,
283
- sparkOpacity: p.spark,
284
164
  };
285
165
  }
@@ -0,0 +1,5 @@
1
+ import type { StatefulIconProps } from "../../shared/icon-types.js";
2
+ import { type FootprintsState } from "./footprints-rig.js";
3
+ export { footprintsStates, type FootprintsState } from "./footprints-rig.js";
4
+ export type FootprintsIconProps = StatefulIconProps<FootprintsState>;
5
+ export declare const FootprintsIcon: import("react").NamedExoticComponent<FootprintsIconProps>;
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { memo } from 'react';
4
+ import { ArticulatedIcon } from "../../shared/articulated-icon.js";
5
+ import { footprintsArt, footprintsStates } from "./footprints-rig.js";
6
+ export { footprintsStates } from "./footprints-rig.js";
7
+ export const FootprintsIcon = memo(function FootprintsIcon(props) {
8
+ return _jsx(ArticulatedIcon, { art: footprintsArt, states: footprintsStates, ...props });
9
+ });
@@ -0,0 +1,4 @@
1
+ import type { Articulation } from "../../shared/articulation.js";
2
+ export declare const footprintsStates: readonly ["idle", "walking", "arrived"];
3
+ export type FootprintsState = (typeof footprintsStates)[number];
4
+ export declare const footprintsArt: Articulation;
@@ -0,0 +1,53 @@
1
+ export const footprintsStates = ['idle', 'walking', 'arrived'];
2
+ // Lucide `footprints` outline with original motion details. Attribution and pinned source: THIRD_PARTY_NOTICES.md.
3
+ // Walking session: quiet footprints, alternating lift and plant while walking, then both soles hold on arrival. Each heel stays attached to its sole.
4
+ // Work loops only while alive; the application determines the result.
5
+ const work = (duration, frames, pause = 0) => ({
6
+ duration,
7
+ repeatAfter: duration + pause,
8
+ loop: true,
9
+ frames,
10
+ });
11
+ const fixed = [{}, {}, {}];
12
+ const p = (name, paths, poses = fixed, options = {}) => ({ name, paths, poses, ...options });
13
+ // Each sole and its heel bar remain one assembly. Steps lift and plant half a stride apart.
14
+ export const footprintsArt = {
15
+ name: 'footprints',
16
+ parts: [
17
+ p('left', [
18
+ 'M4 16v-2.38C4 11.5 2.97 10.5 3 8c.03-2.72 1.49-6 4.5-6C9.37 2 10 3.8 10 5.5c0 3.11-2 5.66-2 8.68V16a2 2 0 1 1-4 0Z',
19
+ 'M4 13h4',
20
+ ], [{ opacity: 0.35 }, {}, {}], {
21
+ pivot: [6, 16],
22
+ gestures: [
23
+ null,
24
+ work(1.22, [
25
+ { at: 0 },
26
+ { at: 0.14 },
27
+ { at: 0.38, y: -0.7, angle: 5, opacity: -0.6 },
28
+ { at: 0.65, y: -0.7, angle: 5, opacity: -0.6 },
29
+ { at: 0.9, angle: -2 },
30
+ { at: 1 },
31
+ ]),
32
+ null,
33
+ ],
34
+ }),
35
+ p('right', [
36
+ 'M20 20v-2.38c0-2.12 1.03-3.12 1-5.62-.03-2.72-1.49-6-4.5-6C14.63 6 14 7.8 14 9.5c0 3.11 2 5.66 2 8.68V20a2 2 0 1 0 4 0Z',
37
+ 'M16 17h4',
38
+ ], [{ opacity: 0.35 }, { y: -0.7, angle: -5, opacity: 0.4 }, {}], {
39
+ pivot: [18, 20],
40
+ gestures: [
41
+ null,
42
+ work(1.22, [
43
+ { at: 0 },
44
+ { at: 0.35, y: 0.7, angle: 5, opacity: 0.6 },
45
+ { at: 0.6, y: 0.7, angle: 5, opacity: 0.6 },
46
+ { at: 0.86 },
47
+ { at: 1 },
48
+ ]),
49
+ null,
50
+ ],
51
+ }),
52
+ ],
53
+ };
@@ -0,0 +1,5 @@
1
+ import type { StatefulIconProps } from "../../shared/icon-types.js";
2
+ import { type FuelState } from "./fuel-rig.js";
3
+ export { fuelStates, type FuelState } from "./fuel-rig.js";
4
+ export type FuelIconProps = StatefulIconProps<FuelState>;
5
+ export declare const FuelIcon: import("react").NamedExoticComponent<FuelIconProps>;
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { memo } from 'react';
4
+ import { ArticulatedIcon } from "../../shared/articulated-icon.js";
5
+ import { fuelArt, fuelStates } from "./fuel-rig.js";
6
+ export { fuelStates } from "./fuel-rig.js";
7
+ export const FuelIcon = memo(function FuelIcon(props) {
8
+ return _jsx(ArticulatedIcon, { art: fuelArt, states: fuelStates, ...props });
9
+ });
@@ -0,0 +1,4 @@
1
+ import type { Articulation } from "../../shared/articulation.js";
2
+ export declare const fuelStates: readonly ["low", "refuelling", "full"];
3
+ export type FuelState = (typeof fuelStates)[number];
4
+ export declare const fuelArt: Articulation;
@@ -0,0 +1,55 @@
1
+ export const fuelStates = ['low', 'refuelling', 'full'];
2
+ // Lucide `fuel` outline with original motion details. Attribution and pinned source: THIRD_PARTY_NOTICES.md.
3
+ // Top-up balance: one short bottom bar, a middle bar charging left to right while pending, and three bars only after confirmation.
4
+ // Work loops only while alive; the application determines the result.
5
+ const work = (duration, frames, pause = 0) => ({
6
+ duration,
7
+ repeatAfter: duration + pause,
8
+ loop: true,
9
+ frames,
10
+ });
11
+ const event = (frames) => ({
12
+ duration: 0.8,
13
+ repeatAfter: 2,
14
+ loop: false,
15
+ frames,
16
+ });
17
+ const fixed = [{}, {}, {}];
18
+ const p = (name, paths, poses = fixed, options = {}) => ({ name, paths, poses, ...options });
19
+ // Top-up: the middle bar receives a left-to-right charge. The last bar is reserved for confirmed full.
20
+ export const fuelArt = {
21
+ name: 'fuel',
22
+ parts: [
23
+ p('pump', ['M14 21V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v16', 'M2 21h13', 'M3 9h11']),
24
+ p('hose', ['M14 13h2a2 2 0 0 1 2 2v2a2 2 0 0 0 4 0v-6.998a2 2 0 0 0-.59-1.42L18 5']),
25
+ p('bar-1', ['M5.5 18.5h6'], [{ scaleX: 0.5 }, {}, {}], {
26
+ accent: true,
27
+ pivot: [5.5, 18.5],
28
+ }),
29
+ p('bar-2', ['M5.5 15.5h6'], [{ opacity: 0, scaleX: 0 }, { scaleX: 0.52 }, {}], {
30
+ accent: true,
31
+ pivot: [5.5, 15.5],
32
+ gestures: [
33
+ null,
34
+ work(1.25, [
35
+ { at: 0 },
36
+ { at: 0.48, scaleX: 0.48 },
37
+ { at: 0.64, scaleX: 0.48 },
38
+ { at: 0.8, opacity: -1, scaleX: 0.48 },
39
+ { at: 0.84, opacity: -1, scaleX: -0.52 },
40
+ { at: 1 },
41
+ ], 0.08),
42
+ null,
43
+ ],
44
+ }),
45
+ p('bar-3', ['M5.5 12.5h6'], [{ opacity: 0, scaleX: 0 }, { opacity: 0, scaleX: 0 }, {}], {
46
+ accent: true,
47
+ pivot: [5.5, 12.5],
48
+ gestures: [
49
+ null,
50
+ null,
51
+ event([{ at: 0, scaleX: -1 }, { at: 0.18, scaleX: -1 }, { at: 0.7 }, { at: 1 }]),
52
+ ],
53
+ }),
54
+ ],
55
+ };
@@ -0,0 +1,5 @@
1
+ import type { StatefulIconProps } from "../../shared/icon-types.js";
2
+ import { type InfinityState } from "./infinity-rig.js";
3
+ export { infinityStates, type InfinityState } from "./infinity-rig.js";
4
+ export type InfinityIconProps = StatefulIconProps<InfinityState>;
5
+ export declare const InfinityIcon: import("react").NamedExoticComponent<InfinityIconProps>;
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { memo, useRef } from 'react';
4
+ import { motion, useTransform } from 'motion/react';
5
+ import { useBehaviorClock, usePoseWeight } from "../../shared/use-icon-motion.js";
6
+ import { useMotionPreference } from "../../shared/use-motion-preference.js";
7
+ import { loopPath } from "./infinity-rig.js";
8
+ export { infinityStates } from "./infinity-rig.js";
9
+ export const InfinityIcon = memo(function InfinityIcon({ state = 'limited', size = 24, color = 'currentColor', strokeWidth = 1.65, speed = 1, alive = false, className, }) {
10
+ const element = useRef(null), reduced = useMotionPreference(), pace = Number.isFinite(speed) ? Math.min(4, Math.max(0.1, speed)) : 1;
11
+ const limited = usePoseWeight(state === 'limited', pace, reduced), running = usePoseWeight(state === 'running', pace, reduced);
12
+ const performs = state === 'running' && alive && !reduced, life = usePoseWeight(performs, pace, reduced), time = useBehaviorClock(element, performs, pace, life);
13
+ const end = useTransform(limited, (v) => 0.2 * Math.max(0, Math.min(1, v))), baseOpacity = useTransform(running, (v) => 1 - 0.75 * Math.max(0, Math.min(1, v)));
14
+ // Keep phase independent of the living fade. One dash traverses the actual closed loop.
15
+ const offset = useTransform(time, (t) => -t / 1.65), traceOpacity = useTransform(running, (v) => Math.max(0, Math.min(1, v)));
16
+ return (_jsx("svg", { ref: element, className: className, width: size, height: size, viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", fill: "none", stroke: color, strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", pointerEvents: "none", style: { display: 'block' }, children: _jsxs("g", { "data-layer": "infinity-body", transform: "translate(12 12) scale(.84) translate(-12 -12)", children: [_jsx(motion.path, { "data-part": "loop", d: loopPath, pathLength: 1, strokeDasharray: "1", strokeDashoffset: end, opacity: baseOpacity }), _jsx(motion.path, { "data-part": "traveller", d: loopPath, pathLength: 1, strokeDasharray: ".2 .8", strokeDashoffset: offset, opacity: traceOpacity })] }) }));
17
+ });
@@ -0,0 +1,3 @@
1
+ export declare const infinityStates: readonly ["limited", "running", "unlimited"];
2
+ export type InfinityState = (typeof infinityStates)[number];
3
+ export declare const loopPath = "M6 16c5 0 7-8 12-8a4 4 0 0 1 0 8c-5 0-7-8-12-8a4 4 0 1 0 0 8";
@@ -0,0 +1,4 @@
1
+ // Lucide `infinity` outline. Attribution and pinned source: THIRD_PARTY_NOTICES.md.
2
+ export const infinityStates = ['limited', 'running', 'unlimited'];
3
+ // Limited holds an open loop; running sends one dash along a ghosted loop; unlimited holds closed.
4
+ export const loopPath = 'M6 16c5 0 7-8 12-8a4 4 0 0 1 0 8c-5 0-7-8-12-8a4 4 0 1 0 0 8';
@@ -0,0 +1,5 @@
1
+ import type { StatefulIconProps } from "../../shared/icon-types.js";
2
+ import { type TargetState } from "./target-rig.js";
3
+ export { targetStates, type TargetState } from "./target-rig.js";
4
+ export type TargetIconProps = StatefulIconProps<TargetState>;
5
+ export declare const TargetIcon: import("react").NamedExoticComponent<TargetIconProps>;
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { memo } from 'react';
4
+ import { ArticulatedIcon } from "../../shared/articulated-icon.js";
5
+ import { targetArt, targetStates } from "./target-rig.js";
6
+ export { targetStates } from "./target-rig.js";
7
+ export const TargetIcon = memo(function TargetIcon(props) {
8
+ return _jsx(ArticulatedIcon, { art: targetArt, states: targetStates, ...props });
9
+ });
@@ -0,0 +1,112 @@
1
+ export declare const targetStates: readonly ["set", "tracking", "hit"];
2
+ export type TargetState = (typeof targetStates)[number];
3
+ export declare const targetArt: {
4
+ readonly name: "target";
5
+ readonly parts: readonly [{
6
+ readonly name: "outer";
7
+ readonly paths: readonly [string];
8
+ readonly poses: readonly [{}, {}, {}];
9
+ readonly pivot: readonly [12, 12];
10
+ readonly gestures: readonly [null, null, {
11
+ readonly frames: readonly [{
12
+ readonly at: 0;
13
+ }, {
14
+ readonly at: 0.35;
15
+ readonly scaleX: 0.04;
16
+ readonly scaleY: 0.04;
17
+ }, {
18
+ readonly at: 0.65;
19
+ readonly scaleX: -0.01;
20
+ readonly scaleY: -0.01;
21
+ }, {
22
+ readonly at: 1;
23
+ }];
24
+ readonly duration: 0.7;
25
+ readonly repeatAfter: 2;
26
+ readonly loop: false;
27
+ }];
28
+ }, {
29
+ readonly name: "middle";
30
+ readonly paths: readonly [string];
31
+ readonly poses: readonly [{}, {
32
+ readonly scaleX: 0.82;
33
+ readonly scaleY: 0.82;
34
+ }, {}];
35
+ readonly pivot: readonly [12, 12];
36
+ readonly gestures: readonly [null, {
37
+ readonly frames: readonly [{
38
+ readonly at: 0;
39
+ }, {
40
+ readonly at: 0.5;
41
+ readonly scaleX: 0.2;
42
+ readonly scaleY: 0.2;
43
+ }, {
44
+ readonly at: 1;
45
+ }];
46
+ readonly duration: 1.5;
47
+ readonly repeatAfter: 2.2;
48
+ readonly loop: true;
49
+ }, {
50
+ readonly frames: readonly [{
51
+ readonly at: 0;
52
+ }, {
53
+ readonly at: 0.3;
54
+ readonly scaleX: -0.06;
55
+ readonly scaleY: -0.06;
56
+ }, {
57
+ readonly at: 0.6;
58
+ readonly scaleX: 0.03;
59
+ readonly scaleY: 0.03;
60
+ }, {
61
+ readonly at: 1;
62
+ }];
63
+ readonly duration: 0.7;
64
+ readonly repeatAfter: 2;
65
+ readonly loop: false;
66
+ }];
67
+ }, {
68
+ readonly name: "centre";
69
+ readonly accent: true;
70
+ readonly paths: readonly [string];
71
+ readonly poses: readonly [{
72
+ readonly opacity: 0.35;
73
+ }, {
74
+ readonly opacity: 0.6;
75
+ readonly scaleX: 0.8;
76
+ readonly scaleY: 0.8;
77
+ }, {}];
78
+ readonly pivot: readonly [12, 12];
79
+ readonly gestures: readonly [null, {
80
+ readonly frames: readonly [{
81
+ readonly at: 0;
82
+ }, {
83
+ readonly at: 0.5;
84
+ readonly opacity: 0.4;
85
+ readonly scaleX: 0.2;
86
+ readonly scaleY: 0.2;
87
+ }, {
88
+ readonly at: 1;
89
+ }];
90
+ readonly duration: 1.5;
91
+ readonly repeatAfter: 2.2;
92
+ readonly loop: true;
93
+ }, {
94
+ readonly frames: readonly [{
95
+ readonly at: 0;
96
+ }, {
97
+ readonly at: 0.3;
98
+ readonly scaleX: 0.35;
99
+ readonly scaleY: 0.35;
100
+ }, {
101
+ readonly at: 0.6;
102
+ readonly scaleX: -0.06;
103
+ readonly scaleY: -0.06;
104
+ }, {
105
+ readonly at: 1;
106
+ }];
107
+ readonly duration: 0.7;
108
+ readonly repeatAfter: 2;
109
+ readonly loop: false;
110
+ }];
111
+ }];
112
+ };