@krizaka/ui 3.41.1 → 3.43.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 (216) hide show
  1. package/dist/RotatingWord-D9s7FXFD.d.ts +46 -0
  2. package/dist/app-shell.d.ts +9 -3
  3. package/dist/app-shell.js +6 -4
  4. package/dist/app-shell.js.map +1 -1
  5. package/dist/bird-plate.js +1 -1
  6. package/dist/{chunk-M4DBVG43.js → chunk-MHUUNC5W.js} +4 -3
  7. package/dist/chunk-MHUUNC5W.js.map +1 -0
  8. package/dist/{chunk-EZC54B5C.js → chunk-MIMOTE4W.js} +3 -3
  9. package/dist/{chunk-EZC54B5C.js.map → chunk-MIMOTE4W.js.map} +1 -1
  10. package/dist/{chunk-CC2FBLLR.js → chunk-P4TTKYC4.js} +2 -2
  11. package/dist/chunk-P4TTKYC4.js.map +1 -0
  12. package/dist/code-block.js +1 -1
  13. package/dist/code-block.js.map +1 -1
  14. package/dist/date-picker.js +1 -1
  15. package/dist/date-picker.js.map +1 -1
  16. package/dist/elephant.d.ts +57 -0
  17. package/dist/elephant.js +61 -0
  18. package/dist/elephant.js.map +1 -0
  19. package/dist/flock.d.ts +7 -1
  20. package/dist/flock.js +386 -50
  21. package/dist/flock.js.map +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/map.js.map +1 -1
  24. package/dist/mascot-quote.js +1 -1
  25. package/dist/mascot-state.js +1 -1
  26. package/dist/mascots.d.ts +3 -1
  27. package/dist/mascots.js +1 -1
  28. package/dist/motion.css +44 -0
  29. package/dist/motion.d.ts +46 -39
  30. package/dist/motion.js +42 -1
  31. package/dist/motion.js.map +1 -1
  32. package/dist/native/map.js.map +1 -1
  33. package/dist/native.js.map +1 -1
  34. package/dist/nav-bar.d.ts +2 -0
  35. package/dist/nav-bar.js +1 -1
  36. package/dist/nav-bar.js.map +1 -1
  37. package/dist/popover.js +1 -1
  38. package/dist/popover.js.map +1 -1
  39. package/dist/rail-nav.js +2 -2
  40. package/dist/rail-nav.js.map +1 -1
  41. package/dist/site-footer.d.ts +15 -8
  42. package/dist/site-footer.js +34 -9
  43. package/dist/site-footer.js.map +1 -1
  44. package/dist/sites.js +1 -1
  45. package/dist/sites.js.map +1 -1
  46. package/dist/tabs.js +1 -1
  47. package/dist/tabs.js.map +1 -1
  48. package/package.json +21 -7
  49. package/registry/account-menu.json +1 -1
  50. package/registry/achievement.json +1 -1
  51. package/registry/action-bar.json +1 -1
  52. package/registry/activity-feed.json +1 -1
  53. package/registry/alert.json +1 -1
  54. package/registry/anatomy-plate.json +1 -1
  55. package/registry/app-header.json +1 -1
  56. package/registry/app-shell.json +11 -3
  57. package/registry/argument-card.json +1 -1
  58. package/registry/audio-player.json +1 -1
  59. package/registry/auth-layout.json +1 -1
  60. package/registry/avatar.json +1 -1
  61. package/registry/badge.json +1 -1
  62. package/registry/bird-plate.json +1 -1
  63. package/registry/button.json +1 -1
  64. package/registry/captcha.json +1 -1
  65. package/registry/card-grid.json +1 -1
  66. package/registry/card.json +1 -1
  67. package/registry/catalogue-page.json +1 -1
  68. package/registry/changelog-page.json +1 -1
  69. package/registry/chat.json +1 -1
  70. package/registry/checkbox.json +1 -1
  71. package/registry/chip-link.json +1 -1
  72. package/registry/chip-row.json +1 -1
  73. package/registry/chip.json +1 -1
  74. package/registry/choice-grid.json +1 -1
  75. package/registry/code-block.json +1 -1
  76. package/registry/combobox.json +1 -1
  77. package/registry/command.json +1 -1
  78. package/registry/comparison-table.json +1 -1
  79. package/registry/component-page.json +1 -1
  80. package/registry/confirm-button.json +1 -1
  81. package/registry/contact-page.json +1 -1
  82. package/registry/continue-prompt.json +1 -1
  83. package/registry/countdown.json +1 -1
  84. package/registry/cover-hero.json +1 -1
  85. package/registry/cta-panel.json +1 -1
  86. package/registry/dashboard-layout.json +1 -1
  87. package/registry/data-table.json +1 -1
  88. package/registry/date-picker.json +1 -1
  89. package/registry/decision-list.json +1 -1
  90. package/registry/description-list.json +1 -1
  91. package/registry/detail-layout.json +1 -1
  92. package/registry/dialog.json +1 -1
  93. package/registry/docs-article-page.json +1 -1
  94. package/registry/docs-hub-page.json +1 -1
  95. package/registry/docs-layout.json +1 -1
  96. package/registry/docs-nav.json +1 -1
  97. package/registry/document-viewer.json +1 -1
  98. package/registry/dropdown-menu.json +1 -1
  99. package/registry/elephant.json +192 -0
  100. package/registry/empty-state.json +1 -1
  101. package/registry/engine-flow.json +1 -1
  102. package/registry/error-page.json +1 -1
  103. package/registry/examples/app-shell/collapse-overflow.d.ts +4 -0
  104. package/registry/examples/app-shell/collapse-overflow.js +35 -0
  105. package/registry/examples/app-shell/collapse-overflow.tsx +28 -0
  106. package/registry/examples/elephant/closing.d.ts +4 -0
  107. package/registry/examples/elephant/closing.js +14 -0
  108. package/registry/examples/elephant/closing.tsx +11 -0
  109. package/registry/examples/elephant/poses.d.ts +4 -0
  110. package/registry/examples/elephant/poses.js +14 -0
  111. package/registry/examples/elephant/poses.tsx +11 -0
  112. package/registry/examples/flock/scenes.d.ts +4 -0
  113. package/registry/examples/flock/scenes.js +28 -0
  114. package/registry/examples/flock/scenes.tsx +24 -0
  115. package/registry/field.json +1 -1
  116. package/registry/file-upload.json +1 -1
  117. package/registry/filter-bar.json +1 -1
  118. package/registry/flock.json +34 -6
  119. package/registry/footnote.json +1 -1
  120. package/registry/force-update-screen.json +1 -1
  121. package/registry/form.json +1 -1
  122. package/registry/gallery-page.json +1 -1
  123. package/registry/genui.json +1 -1
  124. package/registry/glow-card.json +1 -1
  125. package/registry/goal-gauge.json +1 -1
  126. package/registry/how-it-works-page.json +1 -1
  127. package/registry/image-cropper.json +1 -1
  128. package/registry/index.json +40 -9
  129. package/registry/iso.json +1 -1
  130. package/registry/kanban.json +1 -1
  131. package/registry/kbd.json +1 -1
  132. package/registry/landing-page.json +1 -1
  133. package/registry/landscape.json +1 -1
  134. package/registry/language-switch.json +1 -1
  135. package/registry/legal-page.json +1 -1
  136. package/registry/link-card.json +1 -1
  137. package/registry/list.json +1 -1
  138. package/registry/loader.json +1 -1
  139. package/registry/longform-page.json +1 -1
  140. package/registry/maintenance-screen.json +1 -1
  141. package/registry/map.json +2 -2
  142. package/registry/markdown.json +1 -1
  143. package/registry/marketing-layout.json +1 -1
  144. package/registry/marquee.json +1 -1
  145. package/registry/mascot-quote.json +1 -1
  146. package/registry/mascot-state.json +1 -1
  147. package/registry/mascots.json +16 -2
  148. package/registry/match-dialog.json +1 -1
  149. package/registry/media-capture.json +1 -1
  150. package/registry/media-gallery.json +1 -1
  151. package/registry/media-grid.json +1 -1
  152. package/registry/meta-row.json +1 -1
  153. package/registry/meter.json +1 -1
  154. package/registry/nav-bar.json +5 -5
  155. package/registry/number-ticker.json +1 -1
  156. package/registry/opening-hours.json +1 -1
  157. package/registry/page-header.json +1 -1
  158. package/registry/page-hero.json +1 -1
  159. package/registry/page-index.json +1 -1
  160. package/registry/page.json +1 -1
  161. package/registry/pagination.json +1 -1
  162. package/registry/photo-grid.json +1 -1
  163. package/registry/pointer-light.json +1 -1
  164. package/registry/popover.json +2 -2
  165. package/registry/pricing-page.json +1 -1
  166. package/registry/product-page.json +1 -1
  167. package/registry/profile-card.json +1 -1
  168. package/registry/progress.json +1 -1
  169. package/registry/promise-card.json +1 -1
  170. package/registry/radio-group.json +1 -1
  171. package/registry/rail-nav.json +3 -3
  172. package/registry/recipes.json +1 -1
  173. package/registry/scroll-stage.json +1 -1
  174. package/registry/search-field.json +1 -1
  175. package/registry/section-backdrop.json +1 -1
  176. package/registry/separator.json +1 -1
  177. package/registry/service-card.json +1 -1
  178. package/registry/settings-layout.json +1 -1
  179. package/registry/showcase.json +1 -1
  180. package/registry/site-footer.json +35 -7
  181. package/registry/sites.json +2 -2
  182. package/registry/skeleton.json +1 -1
  183. package/registry/skip-link.json +1 -1
  184. package/registry/slider.json +1 -1
  185. package/registry/slot-picker.json +1 -1
  186. package/registry/slot.json +1 -1
  187. package/registry/specimen-tag.json +1 -1
  188. package/registry/spinner.json +1 -1
  189. package/registry/split-view.json +1 -1
  190. package/registry/stage-banner.json +1 -1
  191. package/registry/stat.json +1 -1
  192. package/registry/status-page.json +1 -1
  193. package/registry/step-progress.json +1 -1
  194. package/registry/step-showcase.json +1 -1
  195. package/registry/stepper.json +1 -1
  196. package/registry/sticky-action.json +1 -1
  197. package/registry/swipe-deck.json +1 -1
  198. package/registry/switch.json +1 -1
  199. package/registry/tabs.json +2 -2
  200. package/registry/tag-input.json +1 -1
  201. package/registry/tag-selector.json +1 -1
  202. package/registry/terminal-replay.json +1 -1
  203. package/registry/theme.json +1 -1
  204. package/registry/toast.json +1 -1
  205. package/registry/toc.json +1 -1
  206. package/registry/tooltip.json +1 -1
  207. package/registry/tree-view.json +1 -1
  208. package/registry/update-prompt.json +1 -1
  209. package/registry/verified-badge.json +1 -1
  210. package/registry/vertical-video.json +1 -1
  211. package/registry/video-player.json +1 -1
  212. package/registry/video-trimmer.json +1 -1
  213. package/registry/virtual.json +1 -1
  214. package/registry/waveform.json +1 -1
  215. package/dist/chunk-CC2FBLLR.js.map +0 -1
  216. package/dist/chunk-M4DBVG43.js.map +0 -1
package/dist/flock.js CHANGED
@@ -1,14 +1,232 @@
1
1
  "use client";
2
2
  import {
3
- Mascot
4
- } from "./chunk-M4DBVG43.js";
3
+ Mascot,
4
+ PARCEL
5
+ } from "./chunk-MHUUNC5W.js";
5
6
  import {
6
7
  cn
7
8
  } from "./chunk-WU4VLSEA.js";
8
9
 
9
10
  // src/flock/flock.tsx
11
+ import * as React2 from "react";
12
+
13
+ // src/flock/scenes.tsx
10
14
  import * as React from "react";
11
- import { jsx } from "react/jsx-runtime";
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ var side = (s, i, j) => s.birds[j].x >= s.birds[i].x ? 1 : -1;
17
+ var towards = (s, i, j) => side(s, i, j) > 0 ? "right" : "left";
18
+ function neighbourOf(s, i) {
19
+ const at = s.order.indexOf(i);
20
+ const near = [s.order[at - 1], s.order[at + 1]].filter((n) => n !== void 0);
21
+ if (!near.length) return null;
22
+ return near.reduce((a, b) => Math.abs(s.birds[a].x - s.birds[i].x) <= Math.abs(s.birds[b].x - s.birds[i].x) ? a : b);
23
+ }
24
+ var BOOK_MS = 4800;
25
+ var LOG_MS = 3800;
26
+ var GLINT_MS = 3400;
27
+ var SAY_MS = 1500;
28
+ async function read(s, i) {
29
+ const j = neighbourOf(s, i);
30
+ s.look(i, "left");
31
+ s.show(i, "book", BOOK_MS);
32
+ await s.wait(BOOK_MS * 0.45);
33
+ if (j !== null && s.random() < 0.5) {
34
+ s.look(j, towards(s, j, i));
35
+ await s.wait(1100);
36
+ s.rest(j);
37
+ }
38
+ await s.wait(BOOK_MS * 0.5);
39
+ s.rest(i);
40
+ }
41
+ async function chat(s, i) {
42
+ const j = neighbourOf(s, i);
43
+ s.look(i, j === null ? "up" : towards(s, i, j));
44
+ s.say(i, "\u2026", SAY_MS);
45
+ await s.wait(SAY_MS * 0.6);
46
+ if (j === null) {
47
+ await s.wait(SAY_MS * 0.6);
48
+ s.rest(i);
49
+ return;
50
+ }
51
+ s.look(j, towards(s, j, i));
52
+ await s.wait(SAY_MS * 0.7);
53
+ s.say(j, s.random() < 0.5 ? "!" : "?", SAY_MS);
54
+ s.poke(j);
55
+ await s.wait(SAY_MS * 0.5);
56
+ s.poke(i);
57
+ await s.wait(SAY_MS * 0.7);
58
+ s.rest(i, j);
59
+ }
60
+ async function bow(s, i) {
61
+ const j = neighbourOf(s, i);
62
+ const dir = j === null ? 1 : side(s, i, j);
63
+ const step = `${(s.birds[i].size * 0.14 * dir).toFixed(2)}cqw`;
64
+ const lean = `rotate(${dir * 11}deg)`;
65
+ const at = (x, r) => `translateX(${x}) ${r}`;
66
+ const run = s.move(
67
+ i,
68
+ [
69
+ { transform: at("0cqw", "rotate(0deg)"), easing: "ease-in-out" },
70
+ { transform: at(step, "rotate(0deg)"), offset: 0.22, easing: "ease-in-out" },
71
+ { transform: at(step, lean), offset: 0.42, easing: "ease-in-out" },
72
+ { transform: at(step, lean), offset: 0.6, easing: "ease-in-out" },
73
+ { transform: at(step, "rotate(0deg)"), offset: 0.74, easing: "ease-in-out" },
74
+ { transform: at("0cqw", "rotate(0deg)") }
75
+ ],
76
+ 3800
77
+ );
78
+ if (j !== null) {
79
+ await s.wait(1700);
80
+ s.look(j, towards(s, j, i));
81
+ await s.wait(1200);
82
+ s.poke(j);
83
+ await s.wait(500);
84
+ s.rest(j);
85
+ }
86
+ await run;
87
+ }
88
+ async function tap(s, i) {
89
+ s.show(i, "log", LOG_MS, s.birds[i].x > 50 ? 1 : -1);
90
+ await s.wait(LOG_MS * 0.3);
91
+ for (let n = 0; n < 3; n++) {
92
+ s.poke(i, 420);
93
+ await s.wait(520);
94
+ }
95
+ await s.wait(LOG_MS * 0.3);
96
+ }
97
+ async function shine(s, i) {
98
+ const dir = s.birds[i].x > 50 ? -1 : 1;
99
+ const to = dir > 0 ? "right" : "left";
100
+ s.show(i, "glint", GLINT_MS, dir);
101
+ await s.wait(GLINT_MS * 0.28);
102
+ s.look(i, to);
103
+ await s.wait(GLINT_MS * 0.3);
104
+ s.poke(i);
105
+ await s.wait(GLINT_MS * 0.25);
106
+ s.look(i, "up");
107
+ await s.wait(GLINT_MS * 0.2);
108
+ s.rest(i);
109
+ }
110
+ async function build(s, i) {
111
+ for (let n = 0; n < 4; n++) {
112
+ s.poke(i, 300);
113
+ await s.wait(380);
114
+ }
115
+ }
116
+ async function scan(s, i) {
117
+ for (const to of ["left", "up", "right"]) {
118
+ s.look(i, to);
119
+ await s.wait(1100);
120
+ }
121
+ s.rest(i);
122
+ }
123
+ async function receive(s, i, from) {
124
+ const bird = s.birds[i].bird;
125
+ s.look(i, towards(s, i, from));
126
+ s.show(i, "gift", 2400);
127
+ await s.wait(350);
128
+ if (bird === "crane") await bow(s, i);
129
+ else if (bird === "magpie") {
130
+ s.poke(i);
131
+ await s.wait(700);
132
+ s.show(i, "glint", GLINT_MS * 0.6, side(s, i, from));
133
+ await s.wait(1200);
134
+ } else if (bird === "beaver" || bird === "duck") {
135
+ s.poke(i, 420);
136
+ await s.wait(520);
137
+ s.poke(i, 420);
138
+ await s.wait(900);
139
+ } else if (bird === "owl") {
140
+ s.say(i, "?", SAY_MS);
141
+ await s.wait(900);
142
+ s.poke(i);
143
+ await s.wait(700);
144
+ } else {
145
+ s.say(i, "!", SAY_MS);
146
+ s.poke(i);
147
+ await s.wait(1500);
148
+ }
149
+ }
150
+ var BEATS = [
151
+ { id: "read", bird: "owl", run: read },
152
+ { id: "chat", bird: "flamingo", run: chat },
153
+ { id: "chat", bird: "lovebird", run: chat },
154
+ { id: "bow", bird: "crane", run: bow },
155
+ { id: "tap", bird: "beaver", run: tap },
156
+ { id: "shine", bird: "magpie", run: shine },
157
+ { id: "build", bird: "duck", run: build },
158
+ { id: "scan", bird: "falcon", run: scan }
159
+ ];
160
+ var PAPER = "var(--kz-surface-1)";
161
+ var INK = "var(--kz-text-primary)";
162
+ var LINE = "var(--kz-border-strong, currentColor)";
163
+ function lifeFrames(from, to) {
164
+ return [
165
+ { opacity: 0, transform: from, offset: 0 },
166
+ { opacity: 1, transform: "none", offset: 0.14 },
167
+ { opacity: 1, transform: "none", offset: 0.84 },
168
+ { opacity: 0, transform: to, offset: 1 }
169
+ ];
170
+ }
171
+ var LEAF = [
172
+ { transform: "scaleX(1)", offset: 0 },
173
+ { transform: "scaleX(1)", offset: 0.25 },
174
+ { transform: "scaleX(-1)", offset: 0.38 },
175
+ { transform: "scaleX(1)", offset: 0.39 },
176
+ { transform: "scaleX(1)", offset: 0.62 },
177
+ { transform: "scaleX(-1)", offset: 0.75 },
178
+ { transform: "scaleX(-1)", offset: 1 }
179
+ ];
180
+ function Prop({ shown, size }) {
181
+ const ref = React.useRef(null);
182
+ const leaf = React.useRef(null);
183
+ const dir = shown.side ?? 1;
184
+ React.useEffect(() => {
185
+ const el = ref.current;
186
+ if (!el || typeof el.animate !== "function") return;
187
+ const from = {
188
+ say: ["translateY(30%) scale(.5)", "translateY(-12%) scale(.9)"],
189
+ book: ["translateY(40%) scale(.8)", "translateY(20%) scale(.9)"],
190
+ log: [`translateX(${190 * dir}%)`, `translateX(${190 * dir}%)`],
191
+ glint: ["scale(.2) rotate(-60deg)", `translate(${-90 * dir}%, -170%) scale(.2) rotate(60deg)`],
192
+ gift: ["translateY(40%) scale(.3)", "translateY(-30%) scale(1.4)"]
193
+ };
194
+ const [a, b] = from[shown.kind];
195
+ const animations = [el.animate(lifeFrames(a, b), { duration: shown.ms, fill: "both", easing: "ease-out" })];
196
+ if (shown.kind === "book" && leaf.current) animations.push(leaf.current.animate(LEAF, { duration: shown.ms, fill: "both", easing: "ease-in-out" }));
197
+ if (shown.kind === "glint") animations.push(el.firstElementChild.animate([{ transform: "scale(1)" }, { transform: "scale(1.35)" }, { transform: "scale(1)" }], { duration: 700, iterations: Math.ceil(shown.ms / 700), easing: "ease-in-out" }));
198
+ return () => animations.forEach((x) => x.cancel());
199
+ }, [shown, dir]);
200
+ const unit = (n) => `calc(${size}cqw * ${n})`;
201
+ const base = { position: "absolute", pointerEvents: "none", opacity: 0 };
202
+ if (shown.kind === "say")
203
+ return /* @__PURE__ */ jsxs("div", { ref, "data-flock-prop": "say", style: { ...base, left: "58%", top: "-6%", width: unit(0.34), height: unit(0.24), transformOrigin: "20% 100%" }, children: [
204
+ /* @__PURE__ */ jsx(
205
+ "span",
206
+ {
207
+ style: { position: "absolute", inset: 0, display: "grid", placeItems: "center", background: PAPER, border: `1.5px solid ${LINE}`, borderRadius: "999px", color: INK, font: `600 ${unit(0.17)}/1 var(--font-mono, ui-monospace, monospace)` },
208
+ children: shown.mark ?? "\u2026"
209
+ }
210
+ ),
211
+ /* @__PURE__ */ jsx("span", { style: { position: "absolute", left: "14%", bottom: "-12%", width: unit(0.07), height: unit(0.07), background: PAPER, borderRight: `1.5px solid ${LINE}`, borderBottom: `1.5px solid ${LINE}`, transform: "rotate(45deg)" } })
212
+ ] });
213
+ if (shown.kind === "book")
214
+ return /* @__PURE__ */ jsxs("div", { ref, "data-flock-prop": "book", style: { ...base, left: "17%", bottom: "-2%", width: "66%", height: unit(0.2), transformOrigin: "50% 100%" }, children: [
215
+ [0, 1].map((n) => /* @__PURE__ */ jsx("span", { style: { position: "absolute", top: 0, bottom: 0, [n ? "right" : "left"]: 0, width: "50%", background: `repeating-linear-gradient(${PAPER} 0 18%, ${LINE} 18% 24%)`, border: `1.5px solid ${LINE}`, borderRadius: n ? "0 3px 3px 0" : "3px 0 0 3px" } }, n)),
216
+ /* @__PURE__ */ jsx("div", { ref: leaf, style: { position: "absolute", top: 0, bottom: 0, left: "50%", width: "50%", transformOrigin: "0 50%", background: PAPER, border: `1.5px solid ${LINE}`, borderRadius: "0 3px 3px 0" } })
217
+ ] });
218
+ if (shown.kind === "log")
219
+ return /* @__PURE__ */ jsx("div", { ref, "data-flock-prop": "log", style: { ...base, left: "22%", bottom: "-3%", width: "56%", height: unit(0.17), background: PARCEL[2], borderRadius: "999px", boxShadow: `inset -${unit(0.04)} 0 0 ${PARCEL[1]}` }, children: /* @__PURE__ */ jsx("span", { style: { position: "absolute", left: 0, top: 0, bottom: 0, aspectRatio: "1", borderRadius: "50%", background: `radial-gradient(${PARCEL[0]} 0 25%, ${PARCEL[1]} 26% 55%, ${PARCEL[2]} 56%)`, border: `1px solid ${PARCEL[2]}` } }) });
220
+ if (shown.kind === "glint")
221
+ return /* @__PURE__ */ jsx("div", { ref, "data-flock-prop": "glint", style: { ...base, [dir > 0 ? "left" : "right"]: "94%", bottom: "2%", width: unit(0.2), height: unit(0.2) }, children: /* @__PURE__ */ jsx("span", { style: { position: "absolute", inset: 0, background: PARCEL[0], clipPath: "polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%)" } }) });
222
+ return /* @__PURE__ */ jsxs("div", { ref, "data-flock-prop": "gift", style: { ...base, left: "58%", top: "2%", width: unit(0.26), height: unit(0.22), background: PARCEL[0], border: `1.5px solid ${PARCEL[2]}`, borderRadius: 2 }, children: [
223
+ /* @__PURE__ */ jsx("span", { style: { position: "absolute", left: "44%", top: 0, bottom: 0, width: "12%", background: PARCEL[2] } }),
224
+ /* @__PURE__ */ jsx("span", { style: { position: "absolute", top: "42%", left: 0, right: 0, height: "16%", background: PARCEL[2] } })
225
+ ] });
226
+ }
227
+
228
+ // src/flock/flock.tsx
229
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
12
230
  var GLANCE_HOLD_MS = [1500, 2400];
13
231
  var GLANCE_EVERY_MS = [4200, 9e3];
14
232
  var COURIER_FIRST_MS = 9e3;
@@ -17,26 +235,32 @@ var FLIGHT_MS = 2600;
17
235
  var HAND_OVER_MS = 1300;
18
236
  var LOOK_BACK_MS = 1600;
19
237
  var between = (random, [lo, hi], tempo = 1) => (lo + random() * (hi - lo)) / tempo;
238
+ var SCENE_EVERY_MS = [2600, 5200];
239
+ var SCENE_PAUSE_MS = [8e3, 12e3];
20
240
  var GREET_STEP_MS = 110;
21
241
  var POKE_MS = 700;
22
242
  function useMayMove() {
23
- const [may, setMay] = React.useState(false);
24
- React.useEffect(() => {
243
+ const [may, setMay] = React2.useState(false);
244
+ React2.useEffect(() => {
25
245
  const query = window.matchMedia("(prefers-reduced-motion: reduce)");
26
- const update = () => setMay(!query.matches && document.visibilityState !== "hidden");
246
+ const settled = () => document.documentElement.getAttribute("data-motion") !== "settling";
247
+ const update = () => setMay(!query.matches && document.visibilityState !== "hidden" && settled());
27
248
  update();
28
249
  query.addEventListener("change", update);
29
250
  document.addEventListener("visibilitychange", update);
251
+ const watch = typeof MutationObserver === "undefined" ? null : new MutationObserver(update);
252
+ watch?.observe(document.documentElement, { attributes: true, attributeFilter: ["data-motion"] });
30
253
  return () => {
31
254
  query.removeEventListener("change", update);
32
255
  document.removeEventListener("visibilitychange", update);
256
+ watch?.disconnect();
33
257
  };
34
258
  }, []);
35
259
  return may;
36
260
  }
37
261
  function useOnScreen(ref) {
38
- const [on, setOn] = React.useState(false);
39
- React.useEffect(() => {
262
+ const [on, setOn] = React2.useState(false);
263
+ React2.useEffect(() => {
40
264
  const el = ref.current;
41
265
  if (!el || typeof IntersectionObserver === "undefined") return;
42
266
  const observer = new IntersectionObserver(([entry]) => setOn(Boolean(entry?.isIntersecting)), { threshold: 0.1 });
@@ -45,19 +269,61 @@ function useOnScreen(ref) {
45
269
  }, [ref]);
46
270
  return on;
47
271
  }
48
- function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier = true, react = true, random = Math.random, tempo = 1, active = null, greet = false, className, style, ...props }) {
49
- const stage = React.useRef(null);
50
- const bodies = React.useRef([]);
272
+ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier = true, react = true, scenes = false, random = Math.random, tempo = 1, active = null, greet = false, className, style, ...props }) {
273
+ const stage = React2.useRef(null);
274
+ const bodies = React2.useRef([]);
51
275
  const may = useMayMove();
52
276
  const onScreen = useOnScreen(stage);
53
277
  const running = may && onScreen;
54
- const [looks, setLooks] = React.useState({});
55
- const [flying, setFlying] = React.useState(null);
56
- const [poked, setPoked] = React.useState({});
57
- const order = React.useMemo(() => birds.map((_, i) => i).sort((a, b) => birds[a].x - birds[b].x), [birds]);
58
- const look = (index, to) => setLooks((l) => l[index] === to ? l : { ...l, [index]: to });
59
- const rest = (...indexes) => setLooks((l) => Object.fromEntries(Object.entries(l).filter(([k]) => !indexes.includes(Number(k)))));
60
- React.useEffect(() => {
278
+ const [looks, setLooks] = React2.useState({});
279
+ const [flying, setFlying] = React2.useState(null);
280
+ const [poked, setPoked] = React2.useState({});
281
+ const [shown, setShown] = React2.useState([]);
282
+ const [empty, setEmpty] = React2.useState({});
283
+ const held = React2.useRef(/* @__PURE__ */ new Set());
284
+ const busy = React2.useRef(null);
285
+ const ids = React2.useRef(0);
286
+ const order = React2.useMemo(() => birds.map((_, i) => i).sort((a, b) => birds[a].x - birds[b].x), [birds]);
287
+ const look = React2.useCallback((index, to) => setLooks((l) => l[index] === to ? l : { ...l, [index]: to }), []);
288
+ const rest = React2.useCallback((...indexes) => setLooks((l) => Object.fromEntries(Object.entries(l).filter(([k]) => !indexes.includes(Number(k))))), []);
289
+ const stageFor = React2.useCallback((run) => {
290
+ const later = (fn, ms) => {
291
+ const t = setTimeout(() => {
292
+ run.timers.delete(t);
293
+ fn();
294
+ }, ms);
295
+ run.timers.add(t);
296
+ };
297
+ const poke = (index, ms = POKE_MS) => {
298
+ setPoked((p) => ({ ...p, [index]: true }));
299
+ later(() => setPoked((p) => ({ ...p, [index]: false })), ms);
300
+ };
301
+ const show = (index, kind, ms, side2, mark) => {
302
+ const item = { id: ++ids.current, at: index, kind, ms, side: side2, mark };
303
+ setShown((all) => [...all, item]);
304
+ later(() => setShown((all) => all.filter((x) => x.id !== item.id)), ms);
305
+ };
306
+ return {
307
+ birds,
308
+ order,
309
+ random,
310
+ look,
311
+ rest,
312
+ poke,
313
+ show,
314
+ say: (index, mark, ms) => show(index, "say", ms, void 0, mark),
315
+ wait: (ms) => new Promise((resolve) => later(resolve, ms)),
316
+ move: async (index, keyframes, ms) => {
317
+ const el = bodies.current[index];
318
+ if (!el || typeof el.animate !== "function") return;
319
+ const animation = el.animate(keyframes, { duration: ms });
320
+ run.anims.add(animation);
321
+ await animation.finished.catch(() => void 0);
322
+ run.anims.delete(animation);
323
+ }
324
+ };
325
+ }, [birds, order, random, look, rest]);
326
+ React2.useEffect(() => {
61
327
  if (!running || !glance || order.length < 2) return;
62
328
  let timer;
63
329
  let back;
@@ -65,6 +331,7 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
65
331
  timer = setTimeout(() => {
66
332
  const at = Math.floor(random() * (order.length - 1));
67
333
  const [a, b] = [order[at], order[at + 1]];
334
+ if (held.current.has(a) || held.current.has(b)) return next();
68
335
  look(a, "right");
69
336
  look(b, "left");
70
337
  back = setTimeout(() => {
@@ -78,23 +345,28 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
78
345
  clearTimeout(timer);
79
346
  clearTimeout(back);
80
347
  };
81
- }, [running, glance, order, random, tempo]);
82
- React.useEffect(() => {
348
+ }, [running, glance, order, random, tempo, look, rest]);
349
+ React2.useEffect(() => {
83
350
  const pigeon = birds.findIndex((b) => b.bird === "pigeon");
84
351
  if (!running || !courier || pigeon < 0 || birds.length < 2) return;
85
352
  let alive = true;
353
+ const heldNow = held.current;
86
354
  let timer;
87
355
  let animation;
356
+ const run = { timers: /* @__PURE__ */ new Set(), anims: /* @__PURE__ */ new Set() };
357
+ const from = birds[pigeon];
358
+ const target = birds.reduce((far, b, i) => i !== pigeon && Math.abs(b.x - from.x) > Math.abs(birds[far].x - from.x) ? i : far, pigeon === 0 ? 1 : 0);
88
359
  const wait = (ms) => new Promise((resolve) => timer = setTimeout(resolve, ms));
89
360
  const trip = async () => {
361
+ while (alive && scenes && busy.current === "scene") await wait(400);
362
+ if (!alive) return;
363
+ busy.current = "trip";
90
364
  const el = bodies.current[pigeon];
91
365
  const box = stage.current?.getBoundingClientRect();
92
366
  if (!el || !box || typeof el.animate !== "function") return;
93
- const from = birds[pigeon];
94
- const target = birds.reduce((far, b, i) => i !== pigeon && Math.abs(b.x - from.x) > Math.abs(birds[far].x - from.x) ? i : far, pigeon === 0 ? 1 : 0);
95
367
  const to = birds[target];
96
- const side = to.x > from.x ? 1 : -1;
97
- const dx = (to.x - from.x) / 100 * box.width - side * (to.size / 100) * box.width * 0.55;
368
+ const side2 = to.x > from.x ? 1 : -1;
369
+ const dx = (to.x - from.x) / 100 * box.width - side2 * (to.size / 100) * box.width * 0.55;
98
370
  const lift = from.size / 100 * box.width * 0.35;
99
371
  const fly = async (fromX, toX) => {
100
372
  setFlying({ index: pigeon, bank: Math.sign(toX - fromX) });
@@ -109,21 +381,35 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
109
381
  await animation.finished.catch(() => void 0);
110
382
  setFlying(null);
111
383
  };
112
- look(target, side > 0 ? "left" : "right");
384
+ look(target, side2 > 0 ? "left" : "right");
385
+ held.current.add(target);
113
386
  await fly(0, dx);
114
387
  if (!alive) return;
115
388
  setPoked((p) => ({ ...p, [pigeon]: true }));
116
- await wait(HAND_OVER_MS);
389
+ if (scenes) {
390
+ setEmpty((e) => ({ ...e, [pigeon]: true }));
391
+ const reaction = receive(stageFor(run), target, pigeon);
392
+ await wait(HAND_OVER_MS);
393
+ if (!alive) return;
394
+ setPoked((p) => ({ ...p, [pigeon]: false }));
395
+ await reaction;
396
+ } else {
397
+ await wait(HAND_OVER_MS);
398
+ if (!alive) return;
399
+ setPoked((p) => ({ ...p, [pigeon]: false }));
400
+ }
117
401
  if (!alive) return;
118
- setPoked((p) => ({ ...p, [pigeon]: false }));
119
402
  look(target, "up");
120
403
  await fly(dx, 0);
121
404
  animation?.cancel();
405
+ setEmpty((e) => ({ ...e, [pigeon]: false }));
122
406
  rest(target);
123
407
  };
124
408
  const schedule = (ms) => {
125
409
  timer = setTimeout(async () => {
126
410
  await trip();
411
+ busy.current = null;
412
+ held.current.delete(target);
127
413
  if (alive) schedule(between(random, COURIER_EVERY_MS, tempo));
128
414
  }, ms);
129
415
  };
@@ -132,11 +418,56 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
132
418
  alive = false;
133
419
  clearTimeout(timer);
134
420
  animation?.cancel();
421
+ run.timers.forEach(clearTimeout);
422
+ run.anims.forEach((a) => a.cancel());
423
+ if (scenes) {
424
+ setShown([]);
425
+ setEmpty({});
426
+ heldNow.clear();
427
+ busy.current = null;
428
+ }
135
429
  setFlying(null);
136
430
  };
137
- }, [running, courier, birds, random, tempo]);
138
- const greeted = React.useRef(false);
139
- React.useEffect(() => {
431
+ }, [running, courier, birds, random, tempo, scenes, stageFor, look, rest]);
432
+ React2.useEffect(() => {
433
+ if (!running || !scenes || birds.length < 1) return;
434
+ let alive = true;
435
+ const heldNow = held.current;
436
+ const run = { timers: /* @__PURE__ */ new Set(), anims: /* @__PURE__ */ new Set() };
437
+ const st = stageFor(run);
438
+ const beats = BEATS.flatMap((beat) => birds.flatMap((b, i) => b.bird === beat.bird ? [{ beat, index: i }] : []));
439
+ if (!beats.length) return;
440
+ let last = -1;
441
+ const next = async () => {
442
+ const long = random() < 0.2;
443
+ await st.wait(between(random, long ? SCENE_PAUSE_MS : SCENE_EVERY_MS, tempo));
444
+ while (alive && busy.current === "trip") await st.wait(600);
445
+ if (!alive) return;
446
+ const pool = beats.filter((x) => x.index !== last);
447
+ const pick = (pool.length ? pool : beats)[Math.floor(random() * (pool.length ? pool.length : beats.length))];
448
+ last = pick.index;
449
+ busy.current = "scene";
450
+ const near = neighbourOf(st, pick.index);
451
+ held.current.add(pick.index);
452
+ if (near !== null) held.current.add(near);
453
+ await pick.beat.run(st, pick.index);
454
+ held.current.delete(pick.index);
455
+ if (near !== null) held.current.delete(near);
456
+ if (busy.current === "scene") busy.current = null;
457
+ if (alive) void next();
458
+ };
459
+ void next();
460
+ return () => {
461
+ alive = false;
462
+ run.timers.forEach(clearTimeout);
463
+ run.anims.forEach((a) => a.cancel());
464
+ setShown([]);
465
+ heldNow.clear();
466
+ busy.current = null;
467
+ };
468
+ }, [running, scenes, birds, random, tempo, stageFor]);
469
+ const greeted = React2.useRef(false);
470
+ React2.useEffect(() => {
140
471
  if (!running || !greet || greeted.current) return;
141
472
  greeted.current = true;
142
473
  const timers = [];
@@ -146,7 +477,7 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
146
477
  });
147
478
  return () => timers.forEach(clearTimeout);
148
479
  }, [running, greet, order]);
149
- React.useEffect(() => {
480
+ React2.useEffect(() => {
150
481
  const index = active ? birds.findIndex((b) => b.bird === active) : -1;
151
482
  if (!running || index < 0) return;
152
483
  const start = setTimeout(() => {
@@ -160,7 +491,7 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
160
491
  setPoked((p) => ({ ...p, [index]: false }));
161
492
  rest(index);
162
493
  };
163
- }, [active, running, birds]);
494
+ }, [active, running, birds, look, rest]);
164
495
  const hover = (index, event) => {
165
496
  if (!running || !react || event.pointerType !== "mouse") return;
166
497
  look(index, "up");
@@ -169,7 +500,7 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
169
500
  if (!react) return;
170
501
  rest(index);
171
502
  };
172
- const tap = (index) => {
503
+ const tap2 = (index) => {
173
504
  if (!running || !react) return;
174
505
  look(index, "up");
175
506
  setPoked((p) => ({ ...p, [index]: true }));
@@ -178,17 +509,18 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
178
509
  rest(index);
179
510
  }, LOOK_BACK_MS);
180
511
  };
181
- return /* @__PURE__ */ jsx(
512
+ return /* @__PURE__ */ jsx2(
182
513
  "div",
183
514
  {
184
515
  ref: stage,
185
516
  "aria-hidden": true,
186
517
  "data-flock": "",
187
518
  "data-running": running ? "" : void 0,
519
+ "data-motion-scope": "",
188
520
  className: cn("relative w-full", className),
189
521
  style: { aspectRatio: String(ratio), containerType: "inline-size", ...style },
190
522
  ...props,
191
- children: birds.map((b, i) => /* @__PURE__ */ jsx(
523
+ children: birds.map((b, i) => /* @__PURE__ */ jsxs2(
192
524
  "div",
193
525
  {
194
526
  ref: (el) => {
@@ -199,21 +531,25 @@ function Flock({ birds, ratio = 16 / 9, tone = "brand", glance = true, courier =
199
531
  style: { left: `${b.x - b.size / 2}%`, width: `${b.size}%`, top: `calc(${b.y}% - ${b.size * 0.9}cqw)`, aspectRatio: "1", pointerEvents: react ? "auto" : "none" },
200
532
  onPointerEnter: (event) => hover(i, event),
201
533
  onPointerLeave: () => leave(i),
202
- onPointerDown: () => tap(i),
203
- children: /* @__PURE__ */ jsx(
204
- Mascot,
205
- {
206
- bird: b.bird,
207
- tone,
208
- life: true,
209
- look: looks[i],
210
- flying: flying?.index === i,
211
- bank: flying?.index === i ? flying.bank : 0,
212
- poked: poked[i],
213
- size: 120,
214
- style: { width: "100%", height: "100%", display: "block", overflow: "visible" }
215
- }
216
- )
534
+ onPointerDown: () => tap2(i),
535
+ children: [
536
+ /* @__PURE__ */ jsx2(
537
+ Mascot,
538
+ {
539
+ bird: b.bird,
540
+ tone,
541
+ life: true,
542
+ look: looks[i],
543
+ flying: flying?.index === i,
544
+ bank: flying?.index === i ? flying.bank : 0,
545
+ poked: poked[i],
546
+ carrying: !empty[i],
547
+ size: 120,
548
+ style: { width: "100%", height: "100%", display: "block", overflow: "visible" }
549
+ }
550
+ ),
551
+ shown.filter((x) => x.at === i).map((x) => /* @__PURE__ */ jsx2(Prop, { shown: x, size: b.size }, x.id))
552
+ ]
217
553
  },
218
554
  `${b.bird}-${i}`
219
555
  ))