motionary 7.3.0 → 7.5.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,121 @@
1
+ 'use strict';
2
+
3
+ var registry = require('../chunks/registry-DehBVRDV.cjs');
4
+ require('../chunks/base-BaQV-2ha.cjs');
5
+
6
+ /** Fan-out angles (deg) for `n` floating emoji, centred on straight up (7.4). */
7
+ function fanAngles(n, spread = 60) {
8
+ if (n <= 1)
9
+ return [0];
10
+ return Array.from({ length: n }, (_, i) => Math.round(-spread / 2 + (spread * i) / (n - 1)));
11
+ }
12
+ const span = (cls, text = '') => {
13
+ const s = document.createElement('span');
14
+ s.className = cls;
15
+ s.setAttribute('aria-hidden', 'true');
16
+ s.textContent = text;
17
+ return s;
18
+ };
19
+ const SOCIAL_FX = [
20
+ {
21
+ name: 'typing-dots',
22
+ kind: 'loop',
23
+ description: 'Three dots bounce in a wave inside the element — the “is typing…” indicator (`color`, `period`).',
24
+ defaults: { color: 'currentColor', period: 1100 },
25
+ run: (el, o, ctx) => {
26
+ const box = span('usa-fx-typing');
27
+ Object.assign(box.style, { display: 'inline-flex', gap: '4px', alignItems: 'center', padding: '2px 0' });
28
+ const dots = [0, 1, 2].map(() => {
29
+ const d = span('');
30
+ Object.assign(d.style, { width: '7px', height: '7px', borderRadius: '50%', background: o.color, opacity: '.6', display: 'inline-block' });
31
+ box.appendChild(d);
32
+ return d;
33
+ });
34
+ el.appendChild(box);
35
+ const anims = ctx.reduced ? [] : dots.map((d, i) => ctx.animate(d, [{ transform: 'translateY(0)', opacity: 0.4 }, { transform: 'translateY(-5px)', opacity: 1, offset: 0.3 }, { transform: 'translateY(0)', opacity: 0.4, offset: 0.6 }, { transform: 'translateY(0)', opacity: 0.4 }], { duration: o.period, delay: (i * o.period) / 6, iterations: Infinity }));
36
+ const stop = () => (anims.forEach((a) => a?.cancel()), box.remove());
37
+ ctx.onCleanup(stop);
38
+ return stop;
39
+ },
40
+ },
41
+ {
42
+ name: 'message-in',
43
+ kind: 'enter',
44
+ description: 'A chat bubble pops in from its side (`side` left | right, or `data-side`) with a small overshoot (`duration`).',
45
+ defaults: { side: '', duration: 420 },
46
+ run: (el, o, ctx) => {
47
+ const side = o.side || el.dataset.side || 'left';
48
+ if (ctx.reduced)
49
+ return ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 200 })?.finished.catch(() => undefined);
50
+ el.style.transformOrigin = side === 'right' ? '100% 100%' : '0 100%';
51
+ return ctx.animate(el, [{ transform: `translateX(${side === 'right' ? 24 : -24}px) scale(.6)`, opacity: 0 }, { transform: 'scale(1.04)', opacity: 1, offset: 0.65 }, { transform: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.9,.3,1)' })?.finished.catch(() => undefined);
52
+ },
53
+ },
54
+ {
55
+ name: 'reaction-burst',
56
+ kind: 'click',
57
+ description: 'The reaction emoji (`emoji`, default the element text) floats up in a small fan and fades (`count`, `spread`).',
58
+ defaults: { emoji: '', count: 5, spread: 70, duration: 900 },
59
+ reduced: 'skip',
60
+ run: (el, o, ctx) => {
61
+ const r = el.getBoundingClientRect();
62
+ const emo = o.emoji || (el.textContent || '❤️').trim().slice(0, 2) || '❤️';
63
+ const parts = fanAngles(o.count, o.spread).map((deg, i) => {
64
+ const s = span('', emo);
65
+ Object.assign(s.style, { position: 'fixed', left: `${r.left + r.width / 2 - 10}px`, top: `${r.top}px`, fontSize: '20px', pointerEvents: 'none', zIndex: '2147483000' });
66
+ document.body.appendChild(s);
67
+ const rad = (deg * Math.PI) / 180;
68
+ const dist = 50 + (i % 2) * 18;
69
+ const a = ctx.animate(s, [{ transform: 'translate(0,0) scale(.4)', opacity: 0 }, { transform: `translate(${(Math.sin(rad) * dist * 0.5).toFixed(1)}px,${(-dist * 0.5).toFixed(1)}px) scale(1.1)`, opacity: 1, offset: 0.3 }, { transform: `translate(${(Math.sin(rad) * dist).toFixed(1)}px,${(-Math.cos(rad) * dist - 20).toFixed(1)}px) scale(.9)`, opacity: 0 }], { duration: o.duration, delay: i * 40, easing: 'ease-out' });
70
+ const end = () => s.remove();
71
+ if (a)
72
+ a.finished.then(end, end);
73
+ else
74
+ end();
75
+ ctx.onCleanup(end);
76
+ return a;
77
+ });
78
+ return Promise.all(parts.map((a) => a?.finished.catch(() => undefined)));
79
+ },
80
+ },
81
+ {
82
+ name: 'read-receipt',
83
+ kind: 'enter',
84
+ description: '✓✓ ticks draw in one after the other and turn `color` (blue) — “seen” (`color`).',
85
+ defaults: { color: '#3b82f6', duration: 600 },
86
+ run: (el, o, ctx) => {
87
+ let t = el.querySelector('.usa-fx-ticks');
88
+ if (!t) {
89
+ t = span('usa-fx-ticks', '✓✓');
90
+ Object.assign(t.style, { display: 'inline-block', marginLeft: '4px', letterSpacing: '-4px', fontWeight: '700' });
91
+ el.appendChild(t);
92
+ }
93
+ if (ctx.reduced)
94
+ return void (t.style.color = o.color);
95
+ return ctx.animate(t, [{ clipPath: 'inset(0 100% 0 0)', color: 'currentColor' }, { clipPath: 'inset(0 0 0 0)', color: 'currentColor', offset: 0.6 }, { clipPath: 'inset(0 0 0 0)', color: o.color }], { duration: o.duration, easing: 'ease-out', fill: 'forwards' })?.finished.catch(() => undefined);
96
+ },
97
+ },
98
+ {
99
+ name: 'mention-glow',
100
+ kind: 'attention',
101
+ description: 'A soft highlight sweeps in behind an @mention, then settles (`color`).',
102
+ defaults: { color: 'rgba(250,204,21,.45)', duration: 900 },
103
+ run: (el, o, ctx) => {
104
+ el.style.backgroundImage = `linear-gradient(${o.color},${o.color})`;
105
+ el.style.backgroundRepeat = 'no-repeat';
106
+ el.style.borderRadius = el.style.borderRadius || '4px';
107
+ if (ctx.reduced)
108
+ return void (el.style.backgroundSize = '100% 100%');
109
+ return ctx.animate(el, [{ backgroundSize: '0% 100%' }, { backgroundSize: '100% 100%' }], { duration: o.duration, easing: 'cubic-bezier(.3,.8,.3,1)', fill: 'forwards' })?.finished.catch(() => undefined);
110
+ },
111
+ },
112
+ ];
113
+ /** Register the 7.4 chat & social pack (idempotent). */
114
+ function registerSocialPack() {
115
+ registry.registerEffects(SOCIAL_FX);
116
+ }
117
+
118
+ exports.SOCIAL_FX = SOCIAL_FX;
119
+ exports.fanAngles = fanAngles;
120
+ exports.registerSocialPack = registerSocialPack;
121
+ //# sourceMappingURL=fx-social.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-social.cjs","sources":["../../src/components/fx2/social.ts"],"sourcesContent":["/**\n * 7.4 — Chat & social motion (`motionary/fx/social`, also\n * `motionary/components/fx-social`):\n *\n * - `typing-dots` (loop) — three dots bounce in a wave inside the element.\n * - `message-in` (enter) — a chat bubble pops in from its side (`side`\n * \"left\" | \"right\", or `data-side`), with a little overshoot.\n * - `reaction-burst` (click) — the element's emoji (`emoji`) floats up in a\n * small fan and fades.\n * - `read-receipt` (enter) — ✓✓ ticks draw in and turn blue (`color`).\n * - `mention-glow` (attention) — a soft highlight sweeps behind an @mention.\n *\n * Reduced motion: typing-dots shows static dots, message-in / read-receipt\n * fade, reaction-burst does nothing, mention-glow sets a static highlight.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Fan-out angles (deg) for `n` floating emoji, centred on straight up (7.4). */\nexport function fanAngles(n: number, spread = 60): number[] {\n if (n <= 1) return [0];\n return Array.from({ length: n }, (_, i) => Math.round(-spread / 2 + (spread * i) / (n - 1)));\n}\n\nconst span = (cls: string, text = ''): HTMLSpanElement => {\n const s = document.createElement('span');\n s.className = cls;\n s.setAttribute('aria-hidden', 'true');\n s.textContent = text;\n return s;\n};\n\nexport const SOCIAL_FX: EffectDefinition[] = [\n {\n name: 'typing-dots',\n kind: 'loop',\n description: 'Three dots bounce in a wave inside the element — the “is typing…” indicator (`color`, `period`).',\n defaults: { color: 'currentColor', period: 1100 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const box = span('usa-fx-typing');\n Object.assign(box.style, { display: 'inline-flex', gap: '4px', alignItems: 'center', padding: '2px 0' });\n const dots = [0, 1, 2].map(() => {\n const d = span('');\n Object.assign(d.style, { width: '7px', height: '7px', borderRadius: '50%', background: o.color, opacity: '.6', display: 'inline-block' });\n box.appendChild(d);\n return d;\n });\n el.appendChild(box);\n const anims = ctx.reduced ? [] : dots.map((d, i) => ctx.animate(d, [{ transform: 'translateY(0)', opacity: 0.4 }, { transform: 'translateY(-5px)', opacity: 1, offset: 0.3 }, { transform: 'translateY(0)', opacity: 0.4, offset: 0.6 }, { transform: 'translateY(0)', opacity: 0.4 }], { duration: o.period, delay: (i * o.period) / 6, iterations: Infinity }));\n const stop = () => (anims.forEach((a) => a?.cancel()), box.remove());\n ctx.onCleanup(stop);\n return stop;\n },\n },\n {\n name: 'message-in',\n kind: 'enter',\n description: 'A chat bubble pops in from its side (`side` left | right, or `data-side`) with a small overshoot (`duration`).',\n defaults: { side: '', duration: 420 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const side = o.side || el.dataset.side || 'left';\n if (ctx.reduced) return ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 200 })?.finished.catch(() => undefined);\n el.style.transformOrigin = side === 'right' ? '100% 100%' : '0 100%';\n return ctx.animate(el, [{ transform: `translateX(${side === 'right' ? 24 : -24}px) scale(.6)`, opacity: 0 }, { transform: 'scale(1.04)', opacity: 1, offset: 0.65 }, { transform: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.9,.3,1)' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'reaction-burst',\n kind: 'click',\n description: 'The reaction emoji (`emoji`, default the element text) floats up in a small fan and fades (`count`, `spread`).',\n defaults: { emoji: '', count: 5, spread: 70, duration: 900 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const r = el.getBoundingClientRect();\n const emo = o.emoji || (el.textContent || '❤️').trim().slice(0, 2) || '❤️';\n const parts = fanAngles(o.count, o.spread).map((deg, i) => {\n const s = span('', emo);\n Object.assign(s.style, { position: 'fixed', left: `${r.left + r.width / 2 - 10}px`, top: `${r.top}px`, fontSize: '20px', pointerEvents: 'none', zIndex: '2147483000' });\n document.body.appendChild(s);\n const rad = (deg * Math.PI) / 180;\n const dist = 50 + (i % 2) * 18;\n const a = ctx.animate(s, [{ transform: 'translate(0,0) scale(.4)', opacity: 0 }, { transform: `translate(${(Math.sin(rad) * dist * 0.5).toFixed(1)}px,${(-dist * 0.5).toFixed(1)}px) scale(1.1)`, opacity: 1, offset: 0.3 }, { transform: `translate(${(Math.sin(rad) * dist).toFixed(1)}px,${(-Math.cos(rad) * dist - 20).toFixed(1)}px) scale(.9)`, opacity: 0 }], { duration: o.duration, delay: i * 40, easing: 'ease-out' });\n const end = () => s.remove();\n if (a) a.finished.then(end, end);\n else end();\n ctx.onCleanup(end);\n return a;\n });\n return Promise.all(parts.map((a) => a?.finished.catch(() => undefined)));\n },\n },\n {\n name: 'read-receipt',\n kind: 'enter',\n description: '✓✓ ticks draw in one after the other and turn `color` (blue) — “seen” (`color`).',\n defaults: { color: '#3b82f6', duration: 600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n let t = el.querySelector('.usa-fx-ticks') as HTMLElement | null;\n if (!t) {\n t = span('usa-fx-ticks', '✓✓');\n Object.assign(t.style, { display: 'inline-block', marginLeft: '4px', letterSpacing: '-4px', fontWeight: '700' });\n el.appendChild(t);\n }\n if (ctx.reduced) return void (t.style.color = o.color);\n return ctx.animate(t, [{ clipPath: 'inset(0 100% 0 0)', color: 'currentColor' }, { clipPath: 'inset(0 0 0 0)', color: 'currentColor', offset: 0.6 }, { clipPath: 'inset(0 0 0 0)', color: o.color }], { duration: o.duration, easing: 'ease-out', fill: 'forwards' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'mention-glow',\n kind: 'attention',\n description: 'A soft highlight sweeps in behind an @mention, then settles (`color`).',\n defaults: { color: 'rgba(250,204,21,.45)', duration: 900 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n el.style.backgroundImage = `linear-gradient(${o.color},${o.color})`;\n el.style.backgroundRepeat = 'no-repeat';\n el.style.borderRadius = el.style.borderRadius || '4px';\n if (ctx.reduced) return void (el.style.backgroundSize = '100% 100%');\n return ctx.animate(el, [{ backgroundSize: '0% 100%' }, { backgroundSize: '100% 100%' }], { duration: o.duration, easing: 'cubic-bezier(.3,.8,.3,1)', fill: 'forwards' })?.finished.catch(() => undefined);\n },\n },\n];\n\n/** Register the 7.4 chat & social pack (idempotent). */\nexport function registerSocialPack(): void {\n registerEffects(SOCIAL_FX);\n}\n"],"names":["registerEffects"],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
2
+ type Cleanup = () => void;
3
+
4
+ /**
5
+ * 5.0 — unified plugin-style effect registration. Every effect (built-in or
6
+ * yours) is a plain object registered once and played the same way:
7
+ * `playEffect(el, name)`, `bindEffect(el, name, { trigger })` or
8
+ * `<usa-fx effect="name" trigger="click">`. Effects get a context that
9
+ * already applies reduced motion, motion sensitivity, intensity and the
10
+ * animation budget.
11
+ */
12
+
13
+ declare const EFFECT_KINDS: readonly ["enter", "exit", "attention", "click", "hover", "card", "loop", "page", "background", "text", "cursor", "scroll"];
14
+ type EffectKind = (typeof EFFECT_KINDS)[number];
15
+ interface EffectContext {
16
+ /** Reduced motion applies (OS setting, `minimal` / `static` sensitivity). */
17
+ readonly reduced: boolean;
18
+ readonly sensitivity: MotionSensitivity;
19
+ /** The triggering event (pointer position for click effects), if any. */
20
+ readonly event?: Event;
21
+ /** `el.animate()` with the library's motion rules (may return `null`). */
22
+ animate(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;
23
+ /** Register teardown for long-running effects (loops, listeners). */
24
+ onCleanup(fn: Cleanup): void;
25
+ }
26
+ interface EffectDefinition<O extends Record<string, unknown> = Record<string, any>> {
27
+ /** Unique, kebab-case. */
28
+ name: string;
29
+ kind: EffectKind;
30
+ /** One line for docs and the gallery. */
31
+ description?: string;
32
+ /** Option defaults (merged under the caller's options). */
33
+ defaults?: Partial<O>;
34
+ /**
35
+ * Under reduced motion: `'skip'` (do nothing — default for loop, background
36
+ * and cursor effects) or `'run'` (run with `ctx.reduced === true`, the
37
+ * effect degrades itself — default for everything else).
38
+ */
39
+ reduced?: 'skip' | 'run';
40
+ /** Play the effect. Return an Animation / Promise to be awaited, or a cleanup. */
41
+ run(el: HTMLElement, options: O, ctx: EffectContext): void | Cleanup | Animation | null | Promise<unknown>;
42
+ }
43
+
44
+ /**
45
+ * 7.4 — Chat & social motion (`motionary/fx/social`, also
46
+ * `motionary/components/fx-social`):
47
+ *
48
+ * - `typing-dots` (loop) — three dots bounce in a wave inside the element.
49
+ * - `message-in` (enter) — a chat bubble pops in from its side (`side`
50
+ * "left" | "right", or `data-side`), with a little overshoot.
51
+ * - `reaction-burst` (click) — the element's emoji (`emoji`) floats up in a
52
+ * small fan and fades.
53
+ * - `read-receipt` (enter) — ✓✓ ticks draw in and turn blue (`color`).
54
+ * - `mention-glow` (attention) — a soft highlight sweeps behind an @mention.
55
+ *
56
+ * Reduced motion: typing-dots shows static dots, message-in / read-receipt
57
+ * fade, reaction-burst does nothing, mention-glow sets a static highlight.
58
+ */
59
+
60
+ /** Fan-out angles (deg) for `n` floating emoji, centred on straight up (7.4). */
61
+ declare function fanAngles(n: number, spread?: number): number[];
62
+ declare const SOCIAL_FX: EffectDefinition[];
63
+ /** Register the 7.4 chat & social pack (idempotent). */
64
+ declare function registerSocialPack(): void;
65
+
66
+ export { SOCIAL_FX, fanAngles, registerSocialPack };
@@ -0,0 +1,66 @@
1
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
2
+ type Cleanup = () => void;
3
+
4
+ /**
5
+ * 5.0 — unified plugin-style effect registration. Every effect (built-in or
6
+ * yours) is a plain object registered once and played the same way:
7
+ * `playEffect(el, name)`, `bindEffect(el, name, { trigger })` or
8
+ * `<usa-fx effect="name" trigger="click">`. Effects get a context that
9
+ * already applies reduced motion, motion sensitivity, intensity and the
10
+ * animation budget.
11
+ */
12
+
13
+ declare const EFFECT_KINDS: readonly ["enter", "exit", "attention", "click", "hover", "card", "loop", "page", "background", "text", "cursor", "scroll"];
14
+ type EffectKind = (typeof EFFECT_KINDS)[number];
15
+ interface EffectContext {
16
+ /** Reduced motion applies (OS setting, `minimal` / `static` sensitivity). */
17
+ readonly reduced: boolean;
18
+ readonly sensitivity: MotionSensitivity;
19
+ /** The triggering event (pointer position for click effects), if any. */
20
+ readonly event?: Event;
21
+ /** `el.animate()` with the library's motion rules (may return `null`). */
22
+ animate(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;
23
+ /** Register teardown for long-running effects (loops, listeners). */
24
+ onCleanup(fn: Cleanup): void;
25
+ }
26
+ interface EffectDefinition<O extends Record<string, unknown> = Record<string, any>> {
27
+ /** Unique, kebab-case. */
28
+ name: string;
29
+ kind: EffectKind;
30
+ /** One line for docs and the gallery. */
31
+ description?: string;
32
+ /** Option defaults (merged under the caller's options). */
33
+ defaults?: Partial<O>;
34
+ /**
35
+ * Under reduced motion: `'skip'` (do nothing — default for loop, background
36
+ * and cursor effects) or `'run'` (run with `ctx.reduced === true`, the
37
+ * effect degrades itself — default for everything else).
38
+ */
39
+ reduced?: 'skip' | 'run';
40
+ /** Play the effect. Return an Animation / Promise to be awaited, or a cleanup. */
41
+ run(el: HTMLElement, options: O, ctx: EffectContext): void | Cleanup | Animation | null | Promise<unknown>;
42
+ }
43
+
44
+ /**
45
+ * 7.4 — Chat & social motion (`motionary/fx/social`, also
46
+ * `motionary/components/fx-social`):
47
+ *
48
+ * - `typing-dots` (loop) — three dots bounce in a wave inside the element.
49
+ * - `message-in` (enter) — a chat bubble pops in from its side (`side`
50
+ * "left" | "right", or `data-side`), with a little overshoot.
51
+ * - `reaction-burst` (click) — the element's emoji (`emoji`) floats up in a
52
+ * small fan and fades.
53
+ * - `read-receipt` (enter) — ✓✓ ticks draw in and turn blue (`color`).
54
+ * - `mention-glow` (attention) — a soft highlight sweeps behind an @mention.
55
+ *
56
+ * Reduced motion: typing-dots shows static dots, message-in / read-receipt
57
+ * fade, reaction-burst does nothing, mention-glow sets a static highlight.
58
+ */
59
+
60
+ /** Fan-out angles (deg) for `n` floating emoji, centred on straight up (7.4). */
61
+ declare function fanAngles(n: number, spread?: number): number[];
62
+ declare const SOCIAL_FX: EffectDefinition[];
63
+ /** Register the 7.4 chat & social pack (idempotent). */
64
+ declare function registerSocialPack(): void;
65
+
66
+ export { SOCIAL_FX, fanAngles, registerSocialPack };
@@ -0,0 +1,117 @@
1
+ import { registerEffects } from '../chunks/registry-CyKExAmE.js';
2
+ import '../chunks/base-2-yYc93C.js';
3
+
4
+ /** Fan-out angles (deg) for `n` floating emoji, centred on straight up (7.4). */
5
+ function fanAngles(n, spread = 60) {
6
+ if (n <= 1)
7
+ return [0];
8
+ return Array.from({ length: n }, (_, i) => Math.round(-spread / 2 + (spread * i) / (n - 1)));
9
+ }
10
+ const span = (cls, text = '') => {
11
+ const s = document.createElement('span');
12
+ s.className = cls;
13
+ s.setAttribute('aria-hidden', 'true');
14
+ s.textContent = text;
15
+ return s;
16
+ };
17
+ const SOCIAL_FX = [
18
+ {
19
+ name: 'typing-dots',
20
+ kind: 'loop',
21
+ description: 'Three dots bounce in a wave inside the element — the “is typing…” indicator (`color`, `period`).',
22
+ defaults: { color: 'currentColor', period: 1100 },
23
+ run: (el, o, ctx) => {
24
+ const box = span('usa-fx-typing');
25
+ Object.assign(box.style, { display: 'inline-flex', gap: '4px', alignItems: 'center', padding: '2px 0' });
26
+ const dots = [0, 1, 2].map(() => {
27
+ const d = span('');
28
+ Object.assign(d.style, { width: '7px', height: '7px', borderRadius: '50%', background: o.color, opacity: '.6', display: 'inline-block' });
29
+ box.appendChild(d);
30
+ return d;
31
+ });
32
+ el.appendChild(box);
33
+ const anims = ctx.reduced ? [] : dots.map((d, i) => ctx.animate(d, [{ transform: 'translateY(0)', opacity: 0.4 }, { transform: 'translateY(-5px)', opacity: 1, offset: 0.3 }, { transform: 'translateY(0)', opacity: 0.4, offset: 0.6 }, { transform: 'translateY(0)', opacity: 0.4 }], { duration: o.period, delay: (i * o.period) / 6, iterations: Infinity }));
34
+ const stop = () => (anims.forEach((a) => a?.cancel()), box.remove());
35
+ ctx.onCleanup(stop);
36
+ return stop;
37
+ },
38
+ },
39
+ {
40
+ name: 'message-in',
41
+ kind: 'enter',
42
+ description: 'A chat bubble pops in from its side (`side` left | right, or `data-side`) with a small overshoot (`duration`).',
43
+ defaults: { side: '', duration: 420 },
44
+ run: (el, o, ctx) => {
45
+ const side = o.side || el.dataset.side || 'left';
46
+ if (ctx.reduced)
47
+ return ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 200 })?.finished.catch(() => undefined);
48
+ el.style.transformOrigin = side === 'right' ? '100% 100%' : '0 100%';
49
+ return ctx.animate(el, [{ transform: `translateX(${side === 'right' ? 24 : -24}px) scale(.6)`, opacity: 0 }, { transform: 'scale(1.04)', opacity: 1, offset: 0.65 }, { transform: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.9,.3,1)' })?.finished.catch(() => undefined);
50
+ },
51
+ },
52
+ {
53
+ name: 'reaction-burst',
54
+ kind: 'click',
55
+ description: 'The reaction emoji (`emoji`, default the element text) floats up in a small fan and fades (`count`, `spread`).',
56
+ defaults: { emoji: '', count: 5, spread: 70, duration: 900 },
57
+ reduced: 'skip',
58
+ run: (el, o, ctx) => {
59
+ const r = el.getBoundingClientRect();
60
+ const emo = o.emoji || (el.textContent || '❤️').trim().slice(0, 2) || '❤️';
61
+ const parts = fanAngles(o.count, o.spread).map((deg, i) => {
62
+ const s = span('', emo);
63
+ Object.assign(s.style, { position: 'fixed', left: `${r.left + r.width / 2 - 10}px`, top: `${r.top}px`, fontSize: '20px', pointerEvents: 'none', zIndex: '2147483000' });
64
+ document.body.appendChild(s);
65
+ const rad = (deg * Math.PI) / 180;
66
+ const dist = 50 + (i % 2) * 18;
67
+ const a = ctx.animate(s, [{ transform: 'translate(0,0) scale(.4)', opacity: 0 }, { transform: `translate(${(Math.sin(rad) * dist * 0.5).toFixed(1)}px,${(-dist * 0.5).toFixed(1)}px) scale(1.1)`, opacity: 1, offset: 0.3 }, { transform: `translate(${(Math.sin(rad) * dist).toFixed(1)}px,${(-Math.cos(rad) * dist - 20).toFixed(1)}px) scale(.9)`, opacity: 0 }], { duration: o.duration, delay: i * 40, easing: 'ease-out' });
68
+ const end = () => s.remove();
69
+ if (a)
70
+ a.finished.then(end, end);
71
+ else
72
+ end();
73
+ ctx.onCleanup(end);
74
+ return a;
75
+ });
76
+ return Promise.all(parts.map((a) => a?.finished.catch(() => undefined)));
77
+ },
78
+ },
79
+ {
80
+ name: 'read-receipt',
81
+ kind: 'enter',
82
+ description: '✓✓ ticks draw in one after the other and turn `color` (blue) — “seen” (`color`).',
83
+ defaults: { color: '#3b82f6', duration: 600 },
84
+ run: (el, o, ctx) => {
85
+ let t = el.querySelector('.usa-fx-ticks');
86
+ if (!t) {
87
+ t = span('usa-fx-ticks', '✓✓');
88
+ Object.assign(t.style, { display: 'inline-block', marginLeft: '4px', letterSpacing: '-4px', fontWeight: '700' });
89
+ el.appendChild(t);
90
+ }
91
+ if (ctx.reduced)
92
+ return void (t.style.color = o.color);
93
+ return ctx.animate(t, [{ clipPath: 'inset(0 100% 0 0)', color: 'currentColor' }, { clipPath: 'inset(0 0 0 0)', color: 'currentColor', offset: 0.6 }, { clipPath: 'inset(0 0 0 0)', color: o.color }], { duration: o.duration, easing: 'ease-out', fill: 'forwards' })?.finished.catch(() => undefined);
94
+ },
95
+ },
96
+ {
97
+ name: 'mention-glow',
98
+ kind: 'attention',
99
+ description: 'A soft highlight sweeps in behind an @mention, then settles (`color`).',
100
+ defaults: { color: 'rgba(250,204,21,.45)', duration: 900 },
101
+ run: (el, o, ctx) => {
102
+ el.style.backgroundImage = `linear-gradient(${o.color},${o.color})`;
103
+ el.style.backgroundRepeat = 'no-repeat';
104
+ el.style.borderRadius = el.style.borderRadius || '4px';
105
+ if (ctx.reduced)
106
+ return void (el.style.backgroundSize = '100% 100%');
107
+ return ctx.animate(el, [{ backgroundSize: '0% 100%' }, { backgroundSize: '100% 100%' }], { duration: o.duration, easing: 'cubic-bezier(.3,.8,.3,1)', fill: 'forwards' })?.finished.catch(() => undefined);
108
+ },
109
+ },
110
+ ];
111
+ /** Register the 7.4 chat & social pack (idempotent). */
112
+ function registerSocialPack() {
113
+ registerEffects(SOCIAL_FX);
114
+ }
115
+
116
+ export { SOCIAL_FX, fanAngles, registerSocialPack };
117
+ //# sourceMappingURL=fx-social.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-social.js","sources":["../../src/components/fx2/social.ts"],"sourcesContent":["/**\n * 7.4 — Chat & social motion (`motionary/fx/social`, also\n * `motionary/components/fx-social`):\n *\n * - `typing-dots` (loop) — three dots bounce in a wave inside the element.\n * - `message-in` (enter) — a chat bubble pops in from its side (`side`\n * \"left\" | \"right\", or `data-side`), with a little overshoot.\n * - `reaction-burst` (click) — the element's emoji (`emoji`) floats up in a\n * small fan and fades.\n * - `read-receipt` (enter) — ✓✓ ticks draw in and turn blue (`color`).\n * - `mention-glow` (attention) — a soft highlight sweeps behind an @mention.\n *\n * Reduced motion: typing-dots shows static dots, message-in / read-receipt\n * fade, reaction-burst does nothing, mention-glow sets a static highlight.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Fan-out angles (deg) for `n` floating emoji, centred on straight up (7.4). */\nexport function fanAngles(n: number, spread = 60): number[] {\n if (n <= 1) return [0];\n return Array.from({ length: n }, (_, i) => Math.round(-spread / 2 + (spread * i) / (n - 1)));\n}\n\nconst span = (cls: string, text = ''): HTMLSpanElement => {\n const s = document.createElement('span');\n s.className = cls;\n s.setAttribute('aria-hidden', 'true');\n s.textContent = text;\n return s;\n};\n\nexport const SOCIAL_FX: EffectDefinition[] = [\n {\n name: 'typing-dots',\n kind: 'loop',\n description: 'Three dots bounce in a wave inside the element — the “is typing…” indicator (`color`, `period`).',\n defaults: { color: 'currentColor', period: 1100 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const box = span('usa-fx-typing');\n Object.assign(box.style, { display: 'inline-flex', gap: '4px', alignItems: 'center', padding: '2px 0' });\n const dots = [0, 1, 2].map(() => {\n const d = span('');\n Object.assign(d.style, { width: '7px', height: '7px', borderRadius: '50%', background: o.color, opacity: '.6', display: 'inline-block' });\n box.appendChild(d);\n return d;\n });\n el.appendChild(box);\n const anims = ctx.reduced ? [] : dots.map((d, i) => ctx.animate(d, [{ transform: 'translateY(0)', opacity: 0.4 }, { transform: 'translateY(-5px)', opacity: 1, offset: 0.3 }, { transform: 'translateY(0)', opacity: 0.4, offset: 0.6 }, { transform: 'translateY(0)', opacity: 0.4 }], { duration: o.period, delay: (i * o.period) / 6, iterations: Infinity }));\n const stop = () => (anims.forEach((a) => a?.cancel()), box.remove());\n ctx.onCleanup(stop);\n return stop;\n },\n },\n {\n name: 'message-in',\n kind: 'enter',\n description: 'A chat bubble pops in from its side (`side` left | right, or `data-side`) with a small overshoot (`duration`).',\n defaults: { side: '', duration: 420 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const side = o.side || el.dataset.side || 'left';\n if (ctx.reduced) return ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 200 })?.finished.catch(() => undefined);\n el.style.transformOrigin = side === 'right' ? '100% 100%' : '0 100%';\n return ctx.animate(el, [{ transform: `translateX(${side === 'right' ? 24 : -24}px) scale(.6)`, opacity: 0 }, { transform: 'scale(1.04)', opacity: 1, offset: 0.65 }, { transform: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.9,.3,1)' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'reaction-burst',\n kind: 'click',\n description: 'The reaction emoji (`emoji`, default the element text) floats up in a small fan and fades (`count`, `spread`).',\n defaults: { emoji: '', count: 5, spread: 70, duration: 900 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const r = el.getBoundingClientRect();\n const emo = o.emoji || (el.textContent || '❤️').trim().slice(0, 2) || '❤️';\n const parts = fanAngles(o.count, o.spread).map((deg, i) => {\n const s = span('', emo);\n Object.assign(s.style, { position: 'fixed', left: `${r.left + r.width / 2 - 10}px`, top: `${r.top}px`, fontSize: '20px', pointerEvents: 'none', zIndex: '2147483000' });\n document.body.appendChild(s);\n const rad = (deg * Math.PI) / 180;\n const dist = 50 + (i % 2) * 18;\n const a = ctx.animate(s, [{ transform: 'translate(0,0) scale(.4)', opacity: 0 }, { transform: `translate(${(Math.sin(rad) * dist * 0.5).toFixed(1)}px,${(-dist * 0.5).toFixed(1)}px) scale(1.1)`, opacity: 1, offset: 0.3 }, { transform: `translate(${(Math.sin(rad) * dist).toFixed(1)}px,${(-Math.cos(rad) * dist - 20).toFixed(1)}px) scale(.9)`, opacity: 0 }], { duration: o.duration, delay: i * 40, easing: 'ease-out' });\n const end = () => s.remove();\n if (a) a.finished.then(end, end);\n else end();\n ctx.onCleanup(end);\n return a;\n });\n return Promise.all(parts.map((a) => a?.finished.catch(() => undefined)));\n },\n },\n {\n name: 'read-receipt',\n kind: 'enter',\n description: '✓✓ ticks draw in one after the other and turn `color` (blue) — “seen” (`color`).',\n defaults: { color: '#3b82f6', duration: 600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n let t = el.querySelector('.usa-fx-ticks') as HTMLElement | null;\n if (!t) {\n t = span('usa-fx-ticks', '✓✓');\n Object.assign(t.style, { display: 'inline-block', marginLeft: '4px', letterSpacing: '-4px', fontWeight: '700' });\n el.appendChild(t);\n }\n if (ctx.reduced) return void (t.style.color = o.color);\n return ctx.animate(t, [{ clipPath: 'inset(0 100% 0 0)', color: 'currentColor' }, { clipPath: 'inset(0 0 0 0)', color: 'currentColor', offset: 0.6 }, { clipPath: 'inset(0 0 0 0)', color: o.color }], { duration: o.duration, easing: 'ease-out', fill: 'forwards' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'mention-glow',\n kind: 'attention',\n description: 'A soft highlight sweeps in behind an @mention, then settles (`color`).',\n defaults: { color: 'rgba(250,204,21,.45)', duration: 900 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n el.style.backgroundImage = `linear-gradient(${o.color},${o.color})`;\n el.style.backgroundRepeat = 'no-repeat';\n el.style.borderRadius = el.style.borderRadius || '4px';\n if (ctx.reduced) return void (el.style.backgroundSize = '100% 100%');\n return ctx.animate(el, [{ backgroundSize: '0% 100%' }, { backgroundSize: '100% 100%' }], { duration: o.duration, easing: 'cubic-bezier(.3,.8,.3,1)', fill: 'forwards' })?.finished.catch(() => undefined);\n },\n },\n];\n\n/** Register the 7.4 chat & social pack (idempotent). */\nexport function registerSocialPack(): void {\n registerEffects(SOCIAL_FX);\n}\n"],"names":[],"mappings":"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"}
@@ -13,6 +13,8 @@ var components_fxFocus = require('./fx-focus.cjs');
13
13
  var components_fxMusic = require('./fx-music.cjs');
14
14
  var components_fxChart = require('./fx-chart.cjs');
15
15
  var components_fxShop = require('./fx-shop.cjs');
16
+ var components_fxSocial = require('./fx-social.cjs');
17
+ var components_fxGame = require('./fx-game.cjs');
16
18
  require('../chunks/registry-DehBVRDV.cjs');
17
19
  require('../chunks/base-BaQV-2ha.cjs');
18
20
  require('../chunks/generative-BHIj-NU0.cjs');
@@ -33,6 +35,8 @@ const EFFECT_PACKS = {
33
35
  music: components_fxMusic.MUSIC_FX,
34
36
  chart: components_fxChart.CHART_FX,
35
37
  shop: components_fxShop.SHOP_FX,
38
+ social: components_fxSocial.SOCIAL_FX,
39
+ game: components_fxGame.GAME_FX,
36
40
  };
37
41
  /** Register every 6.x effect pack (idempotent). */
38
42
  function registerEffectPacks() {
@@ -48,6 +52,8 @@ function registerEffectPacks() {
48
52
  components_fxMusic.registerMusicPack();
49
53
  components_fxChart.registerChartPack();
50
54
  components_fxShop.registerShopPack();
55
+ components_fxSocial.registerSocialPack();
56
+ components_fxGame.registerGamePack();
51
57
  }
52
58
 
53
59
  exports.EFFECT_PACK_FORMAT = components_marketplace.EFFECT_PACK_FORMAT;
@@ -99,6 +105,12 @@ exports.registerChartPack = components_fxChart.registerChartPack;
99
105
  exports.SHOP_FX = components_fxShop.SHOP_FX;
100
106
  exports.arcPath = components_fxShop.arcPath;
101
107
  exports.registerShopPack = components_fxShop.registerShopPack;
108
+ exports.SOCIAL_FX = components_fxSocial.SOCIAL_FX;
109
+ exports.fanAngles = components_fxSocial.fanAngles;
110
+ exports.registerSocialPack = components_fxSocial.registerSocialPack;
111
+ exports.GAME_FX = components_fxGame.GAME_FX;
112
+ exports.registerGamePack = components_fxGame.registerGamePack;
113
+ exports.throwPath = components_fxGame.throwPath;
102
114
  exports.EFFECT_PACKS = EFFECT_PACKS;
103
115
  exports.registerEffectPacks = registerEffectPacks;
104
116
  //# sourceMappingURL=fx2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fx2.cjs","sources":["../../src/components/fx2/index.ts"],"sourcesContent":["/**\n * The 6.x effect packs, one entry each (`motionary/components/fx-gpu`, …) so\n * their size budgets stay separate. This module (`registerFx2()`) registers\n * them all — used by dist/widgets.umd.js and the showcase.\n */\nimport type { EffectDefinition } from '../fx/registry';\nexport { EFFECT_PACK_FORMAT, packManifest, validateManifest, loadEffectPack } from './manifest';\nexport type { EffectPackManifest } from './manifest';\nimport { GPU_FX, registerGpuPack } from './gpu';\nimport { TEXT3_FX, registerTextPack, splitChars } from './text3';\nimport { LIGHT_FX, registerLightPack, trackPointer } from './light';\nimport { DEPTH3_FX, register3dPack } from './depth3';\nimport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath } from './morph2';\nimport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions } from './transitions2';\nimport { WEATHER_FX, registerWeatherPack, skyAt } from './weather';\nimport { PHYSICS2_FX, registerPhysicsPack, VerletWorld } from './physics2';\nimport { FOCUS_FX, registerFocusPack } from './focus';\nimport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample } from './music';\nimport { CHART_FX, registerChartPack, parseFigure } from './chart';\nimport { SHOP_FX, registerShopPack, arcPath } from './shop';\n\nexport { GPU_FX, registerGpuPack, TEXT3_FX, registerTextPack, splitChars };\nexport { shaderBackground, supportsWebGL2, fieldFallback, GLSL_HEAD } from './gl';\nexport { supportsWebGPU, glslToWgsl, wgslModule, webgpuBackground, WGSL_HEAD } from './webgpu';\nexport type { ShaderSpec } from './gl';\n\nexport { LIGHT_FX, registerLightPack, trackPointer };\n\nexport { DEPTH3_FX, register3dPack };\n\nexport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath };\n\nexport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions };\n\nexport { WEATHER_FX, registerWeatherPack, skyAt };\n\nexport { PHYSICS2_FX, registerPhysicsPack, VerletWorld };\n\nexport { FOCUS_FX, registerFocusPack };\n\nexport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample };\n\nexport { CHART_FX, registerChartPack, parseFigure };\n\nexport { SHOP_FX, registerShopPack, arcPath };\n\n/** The 6.x effect packs by name. */\nexport const EFFECT_PACKS: Record<string, EffectDefinition[]> = {\n gpu: GPU_FX,\n text: TEXT3_FX,\n light: LIGHT_FX,\n depth: DEPTH3_FX,\n morph: MORPH2_FX,\n transitions: TRANSITIONS2_FX,\n weather: WEATHER_FX,\n physics: PHYSICS2_FX,\n focus: FOCUS_FX,\n music: MUSIC_FX,\n chart: CHART_FX,\n shop: SHOP_FX,\n};\n\n/** Register every 6.x effect pack (idempotent). */\nexport function registerEffectPacks(): void {\n registerGpuPack();\n registerTextPack();\n registerLightPack();\n register3dPack();\n registerMorphPack();\n registerTransitionsPack();\n registerWeatherPack();\n registerPhysicsPack();\n registerFocusPack();\n registerMusicPack();\n registerChartPack();\n registerShopPack();\n}\n\n\n"],"names":["GPU_FX","TEXT3_FX","LIGHT_FX","DEPTH3_FX","MORPH2_FX","TRANSITIONS2_FX","WEATHER_FX","PHYSICS2_FX","FOCUS_FX","MUSIC_FX","CHART_FX","SHOP_FX","registerGpuPack","registerTextPack","registerLightPack","register3dPack","registerMorphPack","registerTransitionsPack","registerWeatherPack","registerPhysicsPack","registerFocusPack","registerMusicPack","registerChartPack","registerShopPack"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA8CA;AACO,MAAM,YAAY,GAAuC;AAC9D,IAAA,GAAG,EAAEA,uBAAM;AACX,IAAA,IAAI,EAAEC,0BAAQ;AACd,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,yBAAS;AAChB,IAAA,KAAK,EAAEC,4BAAS;AAChB,IAAA,WAAW,EAAEC,wCAAe;AAC5B,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,OAAO,EAAEC,gCAAW;AACpB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,IAAI,EAAEC,yBAAO;;AAGf;SACgB,mBAAmB,GAAA;AACjC,IAAAC,gCAAe,EAAE;AACjB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,8BAAc,EAAE;AAChB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,gDAAuB,EAAE;AACzB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,kCAAgB,EAAE;AACpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"fx2.cjs","sources":["../../src/components/fx2/index.ts"],"sourcesContent":["/**\n * The 6.x effect packs, one entry each (`motionary/components/fx-gpu`, …) so\n * their size budgets stay separate. This module (`registerFx2()`) registers\n * them all — used by dist/widgets.umd.js and the showcase.\n */\nimport type { EffectDefinition } from '../fx/registry';\nexport { EFFECT_PACK_FORMAT, packManifest, validateManifest, loadEffectPack } from './manifest';\nexport type { EffectPackManifest } from './manifest';\nimport { GPU_FX, registerGpuPack } from './gpu';\nimport { TEXT3_FX, registerTextPack, splitChars } from './text3';\nimport { LIGHT_FX, registerLightPack, trackPointer } from './light';\nimport { DEPTH3_FX, register3dPack } from './depth3';\nimport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath } from './morph2';\nimport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions } from './transitions2';\nimport { WEATHER_FX, registerWeatherPack, skyAt } from './weather';\nimport { PHYSICS2_FX, registerPhysicsPack, VerletWorld } from './physics2';\nimport { FOCUS_FX, registerFocusPack } from './focus';\nimport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample } from './music';\nimport { CHART_FX, registerChartPack, parseFigure } from './chart';\nimport { SHOP_FX, registerShopPack, arcPath } from './shop';\nimport { SOCIAL_FX, registerSocialPack, fanAngles } from './social';\nimport { GAME_FX, registerGamePack, throwPath } from './game';\n\nexport { GPU_FX, registerGpuPack, TEXT3_FX, registerTextPack, splitChars };\nexport { shaderBackground, supportsWebGL2, fieldFallback, GLSL_HEAD } from './gl';\nexport { supportsWebGPU, glslToWgsl, wgslModule, webgpuBackground, WGSL_HEAD } from './webgpu';\nexport type { ShaderSpec } from './gl';\n\nexport { LIGHT_FX, registerLightPack, trackPointer };\n\nexport { DEPTH3_FX, register3dPack };\n\nexport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath };\n\nexport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions };\n\nexport { WEATHER_FX, registerWeatherPack, skyAt };\n\nexport { PHYSICS2_FX, registerPhysicsPack, VerletWorld };\n\nexport { FOCUS_FX, registerFocusPack };\n\nexport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample };\n\nexport { CHART_FX, registerChartPack, parseFigure };\n\nexport { SHOP_FX, registerShopPack, arcPath };\n\nexport { SOCIAL_FX, registerSocialPack, fanAngles };\n\nexport { GAME_FX, registerGamePack, throwPath };\n\n/** The 6.x effect packs by name. */\nexport const EFFECT_PACKS: Record<string, EffectDefinition[]> = {\n gpu: GPU_FX,\n text: TEXT3_FX,\n light: LIGHT_FX,\n depth: DEPTH3_FX,\n morph: MORPH2_FX,\n transitions: TRANSITIONS2_FX,\n weather: WEATHER_FX,\n physics: PHYSICS2_FX,\n focus: FOCUS_FX,\n music: MUSIC_FX,\n chart: CHART_FX,\n shop: SHOP_FX,\n social: SOCIAL_FX,\n game: GAME_FX,\n};\n\n/** Register every 6.x effect pack (idempotent). */\nexport function registerEffectPacks(): void {\n registerGpuPack();\n registerTextPack();\n registerLightPack();\n register3dPack();\n registerMorphPack();\n registerTransitionsPack();\n registerWeatherPack();\n registerPhysicsPack();\n registerFocusPack();\n registerMusicPack();\n registerChartPack();\n registerShopPack();\n registerSocialPack();\n registerGamePack();\n}\n\n\n"],"names":["GPU_FX","TEXT3_FX","LIGHT_FX","DEPTH3_FX","MORPH2_FX","TRANSITIONS2_FX","WEATHER_FX","PHYSICS2_FX","FOCUS_FX","MUSIC_FX","CHART_FX","SHOP_FX","SOCIAL_FX","GAME_FX","registerGpuPack","registerTextPack","registerLightPack","register3dPack","registerMorphPack","registerTransitionsPack","registerWeatherPack","registerPhysicsPack","registerFocusPack","registerMusicPack","registerChartPack","registerShopPack","registerSocialPack","registerGamePack"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoDA;AACO,MAAM,YAAY,GAAuC;AAC9D,IAAA,GAAG,EAAEA,uBAAM;AACX,IAAA,IAAI,EAAEC,0BAAQ;AACd,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,yBAAS;AAChB,IAAA,KAAK,EAAEC,4BAAS;AAChB,IAAA,WAAW,EAAEC,wCAAe;AAC5B,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,OAAO,EAAEC,gCAAW;AACpB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,MAAM,EAAEC,6BAAS;AACjB,IAAA,IAAI,EAAEC,yBAAO;;AAGf;SACgB,mBAAmB,GAAA;AACjC,IAAAC,gCAAe,EAAE;AACjB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,8BAAc,EAAE;AAChB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,gDAAuB,EAAE;AACzB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,sCAAkB,EAAE;AACpB,IAAAC,kCAAgB,EAAE;AACpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -467,6 +467,54 @@ declare const SHOP_FX: EffectDefinition[];
467
467
  /** Register the 7.3 e-commerce pack (idempotent). */
468
468
  declare function registerShopPack(): void;
469
469
 
470
+ /**
471
+ * 7.4 — Chat & social motion (`motionary/fx/social`, also
472
+ * `motionary/components/fx-social`):
473
+ *
474
+ * - `typing-dots` (loop) — three dots bounce in a wave inside the element.
475
+ * - `message-in` (enter) — a chat bubble pops in from its side (`side`
476
+ * "left" | "right", or `data-side`), with a little overshoot.
477
+ * - `reaction-burst` (click) — the element's emoji (`emoji`) floats up in a
478
+ * small fan and fades.
479
+ * - `read-receipt` (enter) — ✓✓ ticks draw in and turn blue (`color`).
480
+ * - `mention-glow` (attention) — a soft highlight sweeps behind an @mention.
481
+ *
482
+ * Reduced motion: typing-dots shows static dots, message-in / read-receipt
483
+ * fade, reaction-burst does nothing, mention-glow sets a static highlight.
484
+ */
485
+
486
+ /** Fan-out angles (deg) for `n` floating emoji, centred on straight up (7.4). */
487
+ declare function fanAngles(n: number, spread?: number): number[];
488
+ declare const SOCIAL_FX: EffectDefinition[];
489
+ /** Register the 7.4 chat & social pack (idempotent). */
490
+ declare function registerSocialPack(): void;
491
+
492
+ /**
493
+ * 7.5 — Gamification motion (`motionary/fx/game`, also
494
+ * `motionary/components/fx-game`):
495
+ *
496
+ * - `achievement-unlock` (attention) — the element slides in, a light sweep
497
+ * crosses it and its icon (`[data-icon]` or first child) pops.
498
+ * - `level-up` (attention) — a scale-up with a ring shockwave.
499
+ * - `chest-open` (click) — the lid (`[data-lid]` or first child) flips open
500
+ * and sparks fly out.
501
+ * - `coin-burst` (click) — coins (`coin`, default 🪙) arc up and fall.
502
+ * - `xp-gain` (enter) — a “+50 XP” label (`text` or `data-xp`) floats up and
503
+ * fades.
504
+ *
505
+ * Reduced motion: unlock / level-up fade, chest-open sets the lid open,
506
+ * coin-burst and xp-gain do nothing.
507
+ */
508
+
509
+ /** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */
510
+ declare function throwPath(deg: number, power?: number, steps?: number, g?: number): {
511
+ x: number;
512
+ y: number;
513
+ }[];
514
+ declare const GAME_FX: EffectDefinition[];
515
+ /** Register the 7.5 gamification pack (idempotent). */
516
+ declare function registerGamePack(): void;
517
+
470
518
  /**
471
519
  * 5.5 — generative backgrounds on Canvas 2D, registered through
472
520
  * `registerEffect()` (kind `background`): `flow-field`, `voronoi`,
@@ -576,5 +624,5 @@ declare const EFFECT_PACKS: Record<string, EffectDefinition[]>;
576
624
  /** Register every 6.x effect pack (idempotent). */
577
625
  declare function registerEffectPacks(): void;
578
626
 
579
- export { CHART_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FOCUS_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, PHYSICS2_FX, SHOP_FX, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, arcPath, crossDocumentTransitions, fieldFallback, glslToWgsl, loadEffectPack, musicSample, packManifest, pageTransition, parseFigure, pointsToPath, register3dPack, registerChartPack, registerEffectPacks, registerFocusPack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerPhysicsPack, registerShopPack, registerTextPack, registerTransitionsPack, registerWeatherPack, samplePath, shaderBackground, skyAt, splitChars, supportsWebGL2, supportsWebGPU, syntheticSample, trackPointer, validateManifest, webgpuBackground, wgslModule };
627
+ export { CHART_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FOCUS_FX, GAME_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, PHYSICS2_FX, SHOP_FX, SOCIAL_FX, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, arcPath, crossDocumentTransitions, fanAngles, fieldFallback, glslToWgsl, loadEffectPack, musicSample, packManifest, pageTransition, parseFigure, pointsToPath, register3dPack, registerChartPack, registerEffectPacks, registerFocusPack, registerGamePack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerPhysicsPack, registerShopPack, registerSocialPack, registerTextPack, registerTransitionsPack, registerWeatherPack, samplePath, shaderBackground, skyAt, splitChars, supportsWebGL2, supportsWebGPU, syntheticSample, throwPath, trackPointer, validateManifest, webgpuBackground, wgslModule };
580
628
  export type { EffectPackManifest, ShaderSpec };
@@ -467,6 +467,54 @@ declare const SHOP_FX: EffectDefinition[];
467
467
  /** Register the 7.3 e-commerce pack (idempotent). */
468
468
  declare function registerShopPack(): void;
469
469
 
470
+ /**
471
+ * 7.4 — Chat & social motion (`motionary/fx/social`, also
472
+ * `motionary/components/fx-social`):
473
+ *
474
+ * - `typing-dots` (loop) — three dots bounce in a wave inside the element.
475
+ * - `message-in` (enter) — a chat bubble pops in from its side (`side`
476
+ * "left" | "right", or `data-side`), with a little overshoot.
477
+ * - `reaction-burst` (click) — the element's emoji (`emoji`) floats up in a
478
+ * small fan and fades.
479
+ * - `read-receipt` (enter) — ✓✓ ticks draw in and turn blue (`color`).
480
+ * - `mention-glow` (attention) — a soft highlight sweeps behind an @mention.
481
+ *
482
+ * Reduced motion: typing-dots shows static dots, message-in / read-receipt
483
+ * fade, reaction-burst does nothing, mention-glow sets a static highlight.
484
+ */
485
+
486
+ /** Fan-out angles (deg) for `n` floating emoji, centred on straight up (7.4). */
487
+ declare function fanAngles(n: number, spread?: number): number[];
488
+ declare const SOCIAL_FX: EffectDefinition[];
489
+ /** Register the 7.4 chat & social pack (idempotent). */
490
+ declare function registerSocialPack(): void;
491
+
492
+ /**
493
+ * 7.5 — Gamification motion (`motionary/fx/game`, also
494
+ * `motionary/components/fx-game`):
495
+ *
496
+ * - `achievement-unlock` (attention) — the element slides in, a light sweep
497
+ * crosses it and its icon (`[data-icon]` or first child) pops.
498
+ * - `level-up` (attention) — a scale-up with a ring shockwave.
499
+ * - `chest-open` (click) — the lid (`[data-lid]` or first child) flips open
500
+ * and sparks fly out.
501
+ * - `coin-burst` (click) — coins (`coin`, default 🪙) arc up and fall.
502
+ * - `xp-gain` (enter) — a “+50 XP” label (`text` or `data-xp`) floats up and
503
+ * fades.
504
+ *
505
+ * Reduced motion: unlock / level-up fade, chest-open sets the lid open,
506
+ * coin-burst and xp-gain do nothing.
507
+ */
508
+
509
+ /** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */
510
+ declare function throwPath(deg: number, power?: number, steps?: number, g?: number): {
511
+ x: number;
512
+ y: number;
513
+ }[];
514
+ declare const GAME_FX: EffectDefinition[];
515
+ /** Register the 7.5 gamification pack (idempotent). */
516
+ declare function registerGamePack(): void;
517
+
470
518
  /**
471
519
  * 5.5 — generative backgrounds on Canvas 2D, registered through
472
520
  * `registerEffect()` (kind `background`): `flow-field`, `voronoi`,
@@ -576,5 +624,5 @@ declare const EFFECT_PACKS: Record<string, EffectDefinition[]>;
576
624
  /** Register every 6.x effect pack (idempotent). */
577
625
  declare function registerEffectPacks(): void;
578
626
 
579
- export { CHART_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FOCUS_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, PHYSICS2_FX, SHOP_FX, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, arcPath, crossDocumentTransitions, fieldFallback, glslToWgsl, loadEffectPack, musicSample, packManifest, pageTransition, parseFigure, pointsToPath, register3dPack, registerChartPack, registerEffectPacks, registerFocusPack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerPhysicsPack, registerShopPack, registerTextPack, registerTransitionsPack, registerWeatherPack, samplePath, shaderBackground, skyAt, splitChars, supportsWebGL2, supportsWebGPU, syntheticSample, trackPointer, validateManifest, webgpuBackground, wgslModule };
627
+ export { CHART_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FOCUS_FX, GAME_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, PHYSICS2_FX, SHOP_FX, SOCIAL_FX, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, arcPath, crossDocumentTransitions, fanAngles, fieldFallback, glslToWgsl, loadEffectPack, musicSample, packManifest, pageTransition, parseFigure, pointsToPath, register3dPack, registerChartPack, registerEffectPacks, registerFocusPack, registerGamePack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerPhysicsPack, registerShopPack, registerSocialPack, registerTextPack, registerTransitionsPack, registerWeatherPack, samplePath, shaderBackground, skyAt, splitChars, supportsWebGL2, supportsWebGPU, syntheticSample, throwPath, trackPointer, validateManifest, webgpuBackground, wgslModule };
580
628
  export type { EffectPackManifest, ShaderSpec };