@krizaka/ui 3.8.0 → 3.10.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 (342) hide show
  1. package/README.md +13 -9
  2. package/dist/action-bar.js +2 -1
  3. package/dist/action-bar.js.map +1 -1
  4. package/dist/app-shell.d.ts +81 -3
  5. package/dist/app-shell.js +163 -35
  6. package/dist/app-shell.js.map +1 -1
  7. package/dist/audio-player.js +1 -1
  8. package/dist/badge.d.ts +36 -39
  9. package/dist/badge.js +11 -2
  10. package/dist/badge.js.map +1 -1
  11. package/dist/blocks.css +56 -4
  12. package/dist/button-BmCrLCq7.d.ts +114 -0
  13. package/dist/button.d.ts +48 -48
  14. package/dist/button.js +2 -1
  15. package/dist/card.d.ts +111 -111
  16. package/dist/card.js +10 -2
  17. package/dist/card.js.map +1 -1
  18. package/dist/chip.d.ts +24 -24
  19. package/dist/chip.js +10 -2
  20. package/dist/chip.js.map +1 -1
  21. package/dist/{chunk-UOMP6VOZ.js → chunk-276PTQMQ.js} +10 -4
  22. package/dist/chunk-276PTQMQ.js.map +1 -0
  23. package/dist/{chunk-Z6FUPB3Q.js → chunk-2NB27LM7.js} +11 -3
  24. package/dist/chunk-2NB27LM7.js.map +1 -0
  25. package/dist/chunk-2VNYHG4E.js +9 -0
  26. package/dist/chunk-2VNYHG4E.js.map +1 -0
  27. package/dist/{chunk-ND3L5VHT.js → chunk-5Z7FWCV2.js} +2 -2
  28. package/dist/{chunk-YH4LMWRU.js → chunk-7UCPGXKN.js} +11 -3
  29. package/dist/chunk-7UCPGXKN.js.map +1 -0
  30. package/dist/{chunk-AZPKXP3O.js → chunk-AFY35UCB.js} +6 -1
  31. package/dist/{chunk-AZPKXP3O.js.map → chunk-AFY35UCB.js.map} +1 -1
  32. package/dist/{chunk-LCZXS6AK.js → chunk-CKSHLSDH.js} +5 -5
  33. package/dist/chunk-CKSHLSDH.js.map +1 -0
  34. package/dist/chunk-D3T54RSL.js +11 -0
  35. package/dist/chunk-D3T54RSL.js.map +1 -0
  36. package/dist/{chunk-ZKVQGXLD.js → chunk-FKBHWS4N.js} +2 -2
  37. package/dist/{chunk-BRKMQ6JV.js → chunk-FZBWEDQI.js} +1 -23
  38. package/dist/chunk-FZBWEDQI.js.map +1 -0
  39. package/dist/chunk-HG65YAV4.js +379 -0
  40. package/dist/chunk-HG65YAV4.js.map +1 -0
  41. package/dist/{chunk-HCNOOPZE.js → chunk-KVDB4GXV.js} +2 -2
  42. package/dist/chunk-OT6HX3PN.js +85 -0
  43. package/dist/chunk-OT6HX3PN.js.map +1 -0
  44. package/dist/{chunk-RUPNPMP3.js → chunk-OWC2LZD2.js} +11 -3
  45. package/dist/chunk-OWC2LZD2.js.map +1 -0
  46. package/dist/{chunk-FDCMBWUU.js → chunk-REPTKUJ6.js} +4 -4
  47. package/dist/chunk-REPTKUJ6.js.map +1 -0
  48. package/dist/code-block.d.ts +32 -10
  49. package/dist/code-block.js +51 -43
  50. package/dist/code-block.js.map +1 -1
  51. package/dist/combobox.d.ts +3 -3
  52. package/dist/combobox.js +4 -3
  53. package/dist/command.js +3 -2
  54. package/dist/command.js.map +1 -1
  55. package/dist/component-page.js.map +1 -1
  56. package/dist/confirm-button.d.ts +1 -1
  57. package/dist/confirm-button.js +2 -1
  58. package/dist/confirm-button.js.map +1 -1
  59. package/dist/continue-prompt.js +11 -3
  60. package/dist/continue-prompt.js.map +1 -1
  61. package/dist/data-table.js +7 -6
  62. package/dist/data-table.js.map +1 -1
  63. package/dist/date-picker.js +1 -1
  64. package/dist/dialog.js +3 -2
  65. package/dist/dialog.js.map +1 -1
  66. package/dist/file-upload.d.ts +12 -1
  67. package/dist/file-upload.js +73 -89
  68. package/dist/file-upload.js.map +1 -1
  69. package/dist/filter-bar.js +3 -2
  70. package/dist/image-cropper.js +1 -1
  71. package/dist/index.js +9 -367
  72. package/dist/index.js.map +1 -1
  73. package/dist/list.js +1 -1
  74. package/dist/map.js.map +1 -1
  75. package/dist/markdown.d.ts +38 -0
  76. package/dist/markdown.js +150 -0
  77. package/dist/markdown.js.map +1 -0
  78. package/dist/match-dialog.js +2 -1
  79. package/dist/match-dialog.js.map +1 -1
  80. package/dist/media-capture.js +1 -1
  81. package/dist/native/markdown.d.ts +24 -0
  82. package/dist/native/markdown.js +200 -0
  83. package/dist/native/markdown.js.map +1 -0
  84. package/dist/native.d.ts +49 -8
  85. package/dist/native.js +728 -349
  86. package/dist/native.js.map +1 -1
  87. package/dist/nav-bar.d.ts +86 -3
  88. package/dist/nav-bar.js +88 -2
  89. package/dist/nav-bar.js.map +1 -1
  90. package/dist/recipes.d.ts +143 -0
  91. package/dist/recipes.js +180 -0
  92. package/dist/recipes.js.map +1 -0
  93. package/dist/search-field.js +2 -2
  94. package/dist/showcase.d.ts +69 -0
  95. package/dist/showcase.js +218 -0
  96. package/dist/showcase.js.map +1 -0
  97. package/dist/site-footer.d.ts +172 -0
  98. package/dist/site-footer.js +105 -0
  99. package/dist/site-footer.js.map +1 -0
  100. package/dist/sites-CgJrxejx.d.ts +32 -0
  101. package/dist/sites.d.ts +64 -0
  102. package/dist/sites.js +69 -0
  103. package/dist/sites.js.map +1 -0
  104. package/dist/swipe-deck.js +1 -1
  105. package/dist/tag-input.js +4 -3
  106. package/dist/tag-input.js.map +1 -1
  107. package/dist/tag-selector.js +2 -1
  108. package/dist/tag-selector.js.map +1 -1
  109. package/dist/theme.d.ts +1 -1
  110. package/dist/theme.js +2 -1
  111. package/dist/theme.js.map +1 -1
  112. package/dist/tree-view.js +1 -1
  113. package/dist/vertical-video.js +2 -1
  114. package/dist/vertical-video.js.map +1 -1
  115. package/dist/video-player.js +1 -1
  116. package/dist/video-trimmer.js +1 -1
  117. package/dist/virtual.js +2 -2
  118. package/package.json +87 -18
  119. package/registry/achievement.json +1 -1
  120. package/registry/action-bar.json +1 -1
  121. package/registry/activity-feed.json +1 -1
  122. package/registry/alert.json +1 -1
  123. package/registry/app-shell.json +135 -12
  124. package/registry/argument-card.json +1 -1
  125. package/registry/audio-player.json +2 -2
  126. package/registry/auth-layout.json +1 -1
  127. package/registry/avatar.json +1 -1
  128. package/registry/badge.json +9 -3
  129. package/registry/button.json +7 -2
  130. package/registry/card-grid.json +1 -1
  131. package/registry/card.json +8 -3
  132. package/registry/catalogue-page.json +1 -1
  133. package/registry/changelog-page.json +1 -1
  134. package/registry/chat.json +1 -1
  135. package/registry/checkbox.json +1 -1
  136. package/registry/chip-link.json +1 -1
  137. package/registry/chip.json +9 -3
  138. package/registry/choice-grid.json +1 -1
  139. package/registry/code-block.json +65 -21
  140. package/registry/combobox.json +4 -3
  141. package/registry/command.json +1 -1
  142. package/registry/component-page.json +4 -4
  143. package/registry/confirm-button.json +1 -1
  144. package/registry/contact-page.json +1 -1
  145. package/registry/continue-prompt.json +1 -1
  146. package/registry/countdown.json +1 -1
  147. package/registry/cta-panel.json +1 -1
  148. package/registry/dashboard-layout.json +1 -1
  149. package/registry/data-table.json +2 -2
  150. package/registry/date-picker.json +3 -3
  151. package/registry/decision-list.json +1 -1
  152. package/registry/description-list.json +1 -1
  153. package/registry/detail-layout.json +1 -1
  154. package/registry/dialog.json +1 -1
  155. package/registry/docs-article-page.json +1 -1
  156. package/registry/docs-hub-page.json +1 -1
  157. package/registry/docs-layout.json +1 -1
  158. package/registry/dropdown-menu.json +1 -1
  159. package/registry/empty-state.json +1 -1
  160. package/registry/error-page.json +1 -1
  161. package/registry/examples/app-shell/console.d.ts +4 -0
  162. package/registry/examples/app-shell/console.js +93 -0
  163. package/registry/examples/app-shell/console.tsx +103 -0
  164. package/registry/examples/badge/native/dot.dark.png +0 -0
  165. package/registry/examples/badge/native/dot.light.png +0 -0
  166. package/registry/examples/badge/native/scrim.dark.png +0 -0
  167. package/registry/examples/badge/native/scrim.light.png +0 -0
  168. package/registry/examples/badge/native/tones.dark.png +0 -0
  169. package/registry/examples/badge/native/tones.light.png +0 -0
  170. package/registry/examples/card/native/default.dark.png +0 -0
  171. package/registry/examples/card/native/default.light.png +0 -0
  172. package/registry/examples/card/native/elevated.light.png +0 -0
  173. package/registry/examples/chip/native/multiple.dark.png +0 -0
  174. package/registry/examples/chip/native/multiple.light.png +0 -0
  175. package/registry/examples/chip/native/removable.dark.png +0 -0
  176. package/registry/examples/chip/native/removable.light.png +0 -0
  177. package/registry/examples/chip/native/single.dark.png +0 -0
  178. package/registry/examples/chip/native/single.light.png +0 -0
  179. package/registry/examples/chip/native/toggle.dark.png +0 -0
  180. package/registry/examples/chip/native/toggle.light.png +0 -0
  181. package/registry/examples/code-block/annotated.d.ts +4 -0
  182. package/registry/examples/code-block/annotated.js +31 -0
  183. package/registry/examples/code-block/annotated.tsx +26 -0
  184. package/registry/examples/component-page/button.tsx +1 -1
  185. package/registry/examples/form/native/amount.dark.png +0 -0
  186. package/registry/examples/form/native/amount.light.png +0 -0
  187. package/registry/examples/markdown/ai-stream.d.ts +4 -0
  188. package/registry/examples/markdown/ai-stream.js +31 -0
  189. package/registry/examples/markdown/ai-stream.tsx +32 -0
  190. package/registry/examples/markdown/basic.d.ts +4 -0
  191. package/registry/examples/markdown/basic.js +26 -0
  192. package/registry/examples/markdown/basic.tsx +22 -0
  193. package/registry/examples/markdown/native/ai-stream.d.ts +4 -0
  194. package/registry/examples/markdown/native/ai-stream.dark.png +0 -0
  195. package/registry/examples/markdown/native/ai-stream.js +17 -0
  196. package/registry/examples/markdown/native/ai-stream.light.png +0 -0
  197. package/registry/examples/markdown/native/ai-stream.tsx +17 -0
  198. package/registry/examples/markdown/native/basic.d.ts +4 -0
  199. package/registry/examples/markdown/native/basic.dark.png +0 -0
  200. package/registry/examples/markdown/native/basic.js +28 -0
  201. package/registry/examples/markdown/native/basic.light.png +0 -0
  202. package/registry/examples/markdown/native/basic.tsx +27 -0
  203. package/registry/examples/nav-bar/family-admin.d.ts +4 -0
  204. package/registry/examples/nav-bar/family-admin.js +21 -0
  205. package/registry/examples/nav-bar/family-admin.tsx +20 -0
  206. package/registry/examples/nav-bar/family-java.d.ts +4 -0
  207. package/registry/examples/nav-bar/family-java.js +33 -0
  208. package/registry/examples/nav-bar/family-java.tsx +34 -0
  209. package/registry/examples/nav-bar/family-product.d.ts +4 -0
  210. package/registry/examples/nav-bar/family-product.js +35 -0
  211. package/registry/examples/nav-bar/family-product.tsx +39 -0
  212. package/registry/examples/nav-bar/family-ui.d.ts +4 -0
  213. package/registry/examples/nav-bar/family-ui.js +34 -0
  214. package/registry/examples/nav-bar/family-ui.tsx +35 -0
  215. package/registry/examples/nav-bar/family-www.d.ts +4 -0
  216. package/registry/examples/nav-bar/family-www.js +34 -0
  217. package/registry/examples/nav-bar/family-www.tsx +36 -0
  218. package/registry/examples/recipes/tone-chip.d.ts +4 -0
  219. package/registry/examples/recipes/tone-chip.js +46 -0
  220. package/registry/examples/recipes/tone-chip.tsx +32 -0
  221. package/registry/examples/screen/native/profile.dark.png +0 -0
  222. package/registry/examples/screen/native/profile.light.png +0 -0
  223. package/registry/examples/showcase/native/slides.d.ts +4 -0
  224. package/registry/examples/showcase/native/slides.dark.png +0 -0
  225. package/registry/examples/showcase/native/slides.js +27 -0
  226. package/registry/examples/showcase/native/slides.light.png +0 -0
  227. package/registry/examples/showcase/native/slides.tsx +28 -0
  228. package/registry/examples/showcase/prompt-image.d.ts +4 -0
  229. package/registry/examples/showcase/prompt-image.js +29 -0
  230. package/registry/examples/showcase/prompt-image.tsx +28 -0
  231. package/registry/examples/showcase/slides.d.ts +4 -0
  232. package/registry/examples/showcase/slides.js +29 -0
  233. package/registry/examples/showcase/slides.tsx +24 -0
  234. package/registry/examples/site-footer/company.d.ts +4 -0
  235. package/registry/examples/site-footer/company.js +26 -0
  236. package/registry/examples/site-footer/company.tsx +23 -0
  237. package/registry/examples/site-footer/open-source-fr.d.ts +4 -0
  238. package/registry/examples/site-footer/open-source-fr.js +17 -0
  239. package/registry/examples/site-footer/open-source-fr.tsx +17 -0
  240. package/registry/examples/site-footer/product.d.ts +4 -0
  241. package/registry/examples/site-footer/product.js +22 -0
  242. package/registry/examples/site-footer/product.tsx +19 -0
  243. package/registry/examples/sites/family.d.ts +4 -0
  244. package/registry/examples/sites/family.js +20 -0
  245. package/registry/examples/sites/family.tsx +30 -0
  246. package/registry/examples/sites/french.d.ts +4 -0
  247. package/registry/examples/sites/french.js +25 -0
  248. package/registry/examples/sites/french.tsx +25 -0
  249. package/registry/examples/tag-selector/native/interests.dark.png +0 -0
  250. package/registry/examples/tag-selector/native/interests.light.png +0 -0
  251. package/registry/field.json +1 -1
  252. package/registry/file-upload.json +8 -3
  253. package/registry/filter-bar.json +1 -1
  254. package/registry/form.json +2 -2
  255. package/registry/gallery-page.json +1 -1
  256. package/registry/glow-card.json +1 -1
  257. package/registry/goal-gauge.json +1 -1
  258. package/registry/how-it-works-page.json +1 -1
  259. package/registry/image-cropper.json +2 -2
  260. package/registry/index.json +138 -20
  261. package/registry/iso.json +1 -1
  262. package/registry/kanban.json +1 -1
  263. package/registry/kbd.json +1 -1
  264. package/registry/landing-page.json +1 -1
  265. package/registry/landscape.json +1 -1
  266. package/registry/legal-page.json +1 -1
  267. package/registry/link-card.json +1 -1
  268. package/registry/list.json +2 -2
  269. package/registry/loader.json +1 -1
  270. package/registry/longform-page.json +1 -1
  271. package/registry/map.json +3 -3
  272. package/registry/markdown.json +266 -0
  273. package/registry/marketing-layout.json +1 -1
  274. package/registry/marquee.json +1 -1
  275. package/registry/mascot-quote.json +1 -1
  276. package/registry/mascot-state.json +1 -1
  277. package/registry/mascots.json +1 -1
  278. package/registry/match-dialog.json +1 -1
  279. package/registry/media-capture.json +2 -2
  280. package/registry/meter.json +1 -1
  281. package/registry/nav-bar.json +257 -13
  282. package/registry/number-ticker.json +1 -1
  283. package/registry/page-header.json +1 -1
  284. package/registry/page-hero.json +1 -1
  285. package/registry/page.json +1 -1
  286. package/registry/pagination.json +1 -1
  287. package/registry/photo-grid.json +1 -1
  288. package/registry/pointer-light.json +1 -1
  289. package/registry/popover.json +1 -1
  290. package/registry/pricing-page.json +1 -1
  291. package/registry/product-page.json +1 -1
  292. package/registry/profile-card.json +1 -1
  293. package/registry/progress.json +1 -1
  294. package/registry/promise-card.json +1 -1
  295. package/registry/radio-group.json +1 -1
  296. package/registry/recipes.json +99 -0
  297. package/registry/scroll-stage.json +1 -1
  298. package/registry/search-field.json +4 -3
  299. package/registry/section-backdrop.json +1 -1
  300. package/registry/separator.json +1 -1
  301. package/registry/settings-layout.json +1 -1
  302. package/registry/showcase.json +421 -0
  303. package/registry/site-footer.json +389 -0
  304. package/registry/sites.json +93 -0
  305. package/registry/skeleton.json +1 -1
  306. package/registry/skip-link.json +1 -1
  307. package/registry/slider.json +1 -1
  308. package/registry/slot.json +1 -1
  309. package/registry/spinner.json +1 -1
  310. package/registry/split-view.json +1 -1
  311. package/registry/stage-banner.json +1 -1
  312. package/registry/stat.json +1 -1
  313. package/registry/status-page.json +1 -1
  314. package/registry/step-progress.json +1 -1
  315. package/registry/stepper.json +1 -1
  316. package/registry/swipe-deck.json +2 -2
  317. package/registry/switch.json +1 -1
  318. package/registry/tabs.json +1 -1
  319. package/registry/tag-input.json +2 -2
  320. package/registry/tag-selector.json +1 -1
  321. package/registry/terminal-replay.json +1 -1
  322. package/registry/theme.json +1 -1
  323. package/registry/toast.json +1 -1
  324. package/registry/toc.json +1 -1
  325. package/registry/tooltip.json +1 -1
  326. package/registry/tree-view.json +2 -2
  327. package/registry/verified-badge.json +1 -1
  328. package/registry/vertical-video.json +2 -2
  329. package/registry/video-player.json +2 -2
  330. package/registry/video-trimmer.json +2 -2
  331. package/registry/virtual.json +2 -2
  332. package/dist/button-BMAO7dKF.d.ts +0 -114
  333. package/dist/chunk-BRKMQ6JV.js.map +0 -1
  334. package/dist/chunk-FDCMBWUU.js.map +0 -1
  335. package/dist/chunk-LCZXS6AK.js.map +0 -1
  336. package/dist/chunk-RUPNPMP3.js.map +0 -1
  337. package/dist/chunk-UOMP6VOZ.js.map +0 -1
  338. package/dist/chunk-YH4LMWRU.js.map +0 -1
  339. package/dist/chunk-Z6FUPB3Q.js.map +0 -1
  340. /package/dist/{chunk-ND3L5VHT.js.map → chunk-5Z7FWCV2.js.map} +0 -0
  341. /package/dist/{chunk-ZKVQGXLD.js.map → chunk-FKBHWS4N.js.map} +0 -0
  342. /package/dist/{chunk-HCNOOPZE.js.map → chunk-KVDB4GXV.js.map} +0 -0
package/dist/native.js CHANGED
@@ -519,22 +519,22 @@ var UNITS = [
519
519
  ];
520
520
  function timeAgo(at, { now = /* @__PURE__ */ new Date(), locale = "en-US", style = "short" } = {}) {
521
521
  let value = (new Date(at).getTime() - now.getTime()) / 1e3;
522
- let unit = "second";
522
+ let unit2 = "second";
523
523
  for (const [name, size] of UNITS) {
524
- unit = name;
524
+ unit2 = name;
525
525
  if (Math.abs(value) < size - 0.5) break;
526
526
  value /= size;
527
527
  }
528
- return new Intl.RelativeTimeFormat(locale, { numeric: "auto", style }).format(Math.round(value) + 0, unit);
528
+ return new Intl.RelativeTimeFormat(locale, { numeric: "auto", style }).format(Math.round(value) + 0, unit2);
529
529
  }
530
530
 
531
531
  // src/native/activity-feed.tsx
532
532
  import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
533
533
  var LABELS = { today: "Today", yesterday: "Yesterday", times: (n) => `\xD7${n}`, newEvents: (n) => n === 1 ? "1 new event" : `${n} new events` };
534
534
  var tone = (t, name) => ({ neutral: t.borderStrong, accent: t.accent, success: t.success, warning: t.warning, danger: t.danger, info: t.info })[name ?? "neutral"];
535
- function ActivityFeed({ events, "aria-label": label, locale = "en-US", now: given, fold = true, live, leading, empty, labels: words, style }) {
535
+ function ActivityFeed({ events, "aria-label": label, locale = "en-US", now: given, fold = true, live, leading, empty: empty2, labels: words2, style }) {
536
536
  const { theme } = useTheme();
537
- const labels = { ...LABELS, ...words };
537
+ const labels = { ...LABELS, ...words2 };
538
538
  const [tick, setTick] = React3.useState(() => given ?? /* @__PURE__ */ new Date());
539
539
  React3.useEffect(() => {
540
540
  if (given) return;
@@ -557,7 +557,7 @@ function ActivityFeed({ events, "aria-label": label, locale = "en-US", now: give
557
557
  sections,
558
558
  keyExtractor: (item) => item.event.id,
559
559
  stickySectionHeadersEnabled: true,
560
- ListEmptyComponent: empty ? /* @__PURE__ */ jsx4(Fragment, { children: empty }) : null,
560
+ ListEmptyComponent: empty2 ? /* @__PURE__ */ jsx4(Fragment, { children: empty2 }) : null,
561
561
  renderSectionHeader: ({ section }) => /* @__PURE__ */ jsx4(View2, { style: [styles3.heading, { backgroundColor: theme.surface0 }], children: /* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", role: "heading", style: styles3.headingText, children: section.title }) }),
562
562
  renderItem: ({ item: { event, count } }) => /* @__PURE__ */ jsxs2(View2, { style: styles3.row, accessible: true, children: [
563
563
  leading ? leading(event) : /* @__PURE__ */ jsx4(View2, { "aria-hidden": true, style: [styles3.marker, { backgroundColor: tone(theme, event.tone) }] }),
@@ -669,24 +669,217 @@ var styles4 = StyleSheet4.create({
669
669
  // src/native/badge.tsx
670
670
  import * as React5 from "react";
671
671
  import { Animated, StyleSheet as StyleSheet5, Text as Text3 } from "react-native";
672
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
673
- function look(tone3, t) {
674
- switch (tone3) {
675
- case "accent":
676
- return { bg: t.accentSoft, fg: t.textPrimary, border: alpha(t.accent, 0.4), dot: t.accent };
677
- case "success":
678
- case "warning":
679
- case "danger":
680
- return { bg: alpha(t[tone3], 0.15), fg: t.textPrimary, border: alpha(t[tone3], 0.4), dot: t[tone3] };
681
- case "scrim":
682
- return { bg: t.scrim, fg: t.textOnMedia, border: "transparent", dot: t.textOnMedia };
683
- default:
684
- return { bg: t.surface3, fg: t.textSecondary, border: "transparent", dot: t.textSecondary };
672
+
673
+ // src/recipes/define.ts
674
+ function defineRecipe(config) {
675
+ return config;
676
+ }
677
+
678
+ // src/badge/recipe.ts
679
+ var badgeRecipe = defineRecipe({
680
+ base: "inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-full font-semibold uppercase tracking-wider",
681
+ variants: {
682
+ tone: {
683
+ neutral: "bg-surface-3 text-fg-secondary",
684
+ accent: "bg-accent-soft text-fg ring-1 ring-inset ring-accent/40 [&>[data-dot]]:bg-accent",
685
+ success: "bg-success/15 text-fg ring-1 ring-inset ring-success/40 [&>[data-dot]]:bg-success",
686
+ warning: "bg-warning/15 text-fg ring-1 ring-inset ring-warning/40 [&>[data-dot]]:bg-warning",
687
+ danger: "bg-danger/15 text-fg ring-1 ring-inset ring-danger/40 [&>[data-dot]]:bg-danger",
688
+ /** On a media: veil and text invariant, identical in both themes. */
689
+ scrim: "bg-scrim text-fg-on-media backdrop-blur-md"
690
+ },
691
+ size: { sm: "px-2 py-0.5 text-[10px]", md: "px-2.5 py-1 text-[11px]" },
692
+ pulse: { true: "[&>[data-dot]]:motion-safe:animate-pulse" }
693
+ },
694
+ defaultVariants: { tone: "neutral", size: "sm" }
695
+ });
696
+
697
+ // src/recipes/roles.ts
698
+ var ROLES = {
699
+ "surface-0": "surface0",
700
+ "surface-1": "surface1",
701
+ "surface-2": "surface2",
702
+ "surface-3": "surface3",
703
+ media: "media",
704
+ scrim: "scrim",
705
+ "scrim-strong": "scrimStrong",
706
+ overlay: "overlay",
707
+ "border-subtle": "borderSubtle",
708
+ "border-default": "borderDefault",
709
+ "border-strong": "borderStrong",
710
+ fg: "textPrimary",
711
+ "fg-secondary": "textSecondary",
712
+ "fg-muted": "textMuted",
713
+ "fg-on-media": "textOnMedia",
714
+ "fg-accent": "accentText",
715
+ "fg-success": "successText",
716
+ "fg-warning": "warningText",
717
+ "fg-danger": "dangerText",
718
+ "fg-info": "infoText",
719
+ accent: "accent",
720
+ "accent-hover": "accentHover",
721
+ "accent-soft": "accentSoft",
722
+ "accent-2": "accent2",
723
+ "on-accent": "onAccent",
724
+ ring: "ring",
725
+ success: "success",
726
+ warning: "warning",
727
+ danger: "danger",
728
+ info: "info",
729
+ "success-soft": "successSoft",
730
+ "warning-soft": "warningSoft",
731
+ "danger-soft": "dangerSoft",
732
+ glass: "glassBg",
733
+ "glass-border": "glassBorder"
734
+ };
735
+ var TEXT_SIZES = { xs: 12, sm: 14, base: 16, lg: 18, xl: 20, "2xl": 24, "3xl": 30 };
736
+ var FONT_WEIGHTS = { normal: "400", medium: "500", semibold: "600", bold: "700", extrabold: "800", black: "900" };
737
+ var TRACKING = { tighter: -0.05, tight: -0.025, normal: 0, wide: 0.025, wider: 0.05, widest: 0.1 };
738
+
739
+ // src/recipes/native.ts
740
+ var BASE = "base";
741
+ var words = (value) => typeof value === "string" ? value.split(/\s+/).filter(Boolean) : Array.isArray(value) ? value.flatMap(words) : [];
742
+ function withAlpha(color, opacity) {
743
+ const hex = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);
744
+ if (!hex) return color;
745
+ const [r, g, b] = hex.slice(1).map((part) => parseInt(part, 16));
746
+ return `rgba(${r},${g},${b},${opacity})`;
747
+ }
748
+ function slotNames(config) {
749
+ return config.slots ? Object.keys(config.slots) : [BASE];
750
+ }
751
+ function classesFor(config, props) {
752
+ const names = slotNames(config);
753
+ const out = Object.fromEntries(names.map((name) => [name, config.slots ? words(config.slots[name]) : words(config.base)]));
754
+ const add = (value) => {
755
+ if (typeof value === "string" || Array.isArray(value)) (out[BASE] ??= []).push(...words(value));
756
+ else if (value && typeof value === "object") for (const [name, classes] of Object.entries(value)) (out[name] ??= []).push(...words(classes));
757
+ };
758
+ const chosen = { ...config.defaultVariants, ...Object.fromEntries(Object.entries(props).filter(([, v]) => v !== void 0)) };
759
+ for (const [dimension, values] of Object.entries(config.variants ?? {})) {
760
+ const key = String(chosen[dimension]);
761
+ if (key in values) add(values[key]);
762
+ }
763
+ for (const compound of config.compoundVariants ?? []) {
764
+ const { class: a, className: b, ...conditions } = compound;
765
+ const matches = Object.entries(conditions).every(([dimension, expected]) => Array.isArray(expected) ? expected.map(String).includes(String(chosen[dimension])) : String(chosen[dimension]) === String(expected));
766
+ if (matches) add(a ?? b);
685
767
  }
768
+ return out;
769
+ }
770
+ var empty = () => ({ frame: {}, text: {}, disabled: { frame: {}, text: {} }, on: { frame: {}, text: {} }, ignored: [] });
771
+ var unit = (value) => /^\d+(\.\d+)?$/.test(value) ? Number(value) * 4 : void 0;
772
+ function colour(name, theme) {
773
+ const [role, percent] = name.split("/");
774
+ if (role === "transparent") return "transparent";
775
+ if (!role || !(role in ROLES)) return void 0;
776
+ const resolved = theme[ROLES[role]];
777
+ if (resolved === void 0) return void 0;
778
+ return percent === void 0 ? resolved : withAlpha(resolved, Number(percent) / 100);
779
+ }
780
+ function apply(look3, cls, theme) {
781
+ let target = look3;
782
+ let utility = cls;
783
+ if (cls.startsWith("disabled:")) {
784
+ target = look3.disabled;
785
+ utility = cls.slice("disabled:".length);
786
+ } else if (cls.startsWith("data-[state=on]:")) {
787
+ target = look3.on;
788
+ utility = cls.slice("data-[state=on]:".length);
789
+ } else if (cls.startsWith("[&>[data-dot]]:bg-")) {
790
+ const dot = colour(cls.slice("[&>[data-dot]]:bg-".length), theme);
791
+ if (dot === void 0) return false;
792
+ look3.dot = dot;
793
+ return true;
794
+ }
795
+ if (utility.includes(":") || utility.startsWith("[&")) return false;
796
+ const { frame, text } = target;
797
+ let match;
798
+ if (utility.startsWith("bg-linear-to-")) return true;
799
+ if (match = /^bg-(.+)$/.exec(utility)) {
800
+ const value = colour(match[1], theme);
801
+ if (value === void 0) return false;
802
+ frame.backgroundColor = value;
803
+ return true;
804
+ }
805
+ if (match = /^text-(.+)$/.exec(utility)) {
806
+ const arbitrary = /^\[(\d+(?:\.\d+)?)px\]$/.exec(match[1]);
807
+ if (arbitrary) return text.fontSize = Number(arbitrary[1]), true;
808
+ if (match[1] in TEXT_SIZES) return text.fontSize = TEXT_SIZES[match[1]], true;
809
+ const value = colour(match[1], theme);
810
+ if (value === void 0) return false;
811
+ text.color = value;
812
+ return true;
813
+ }
814
+ if (utility === "border") return frame.borderWidth = 1, true;
815
+ if (match = /^(?:border|ring)-(.+)$/.exec(utility)) {
816
+ if (match[1] === "1") return frame.borderWidth = 1, true;
817
+ if (match[1] === "inset") return true;
818
+ const value = colour(match[1], theme);
819
+ if (value === void 0) return false;
820
+ frame.borderColor = value;
821
+ return true;
822
+ }
823
+ if (utility === "ring-inset") return true;
824
+ if (match = /^(h|w|min-w|px|py|p|gap)-(\d+(?:\.\d+)?)$/.exec(utility)) {
825
+ const points = unit(match[2]);
826
+ const key = { h: "height", w: "width", "min-w": "minWidth", px: "paddingHorizontal", py: "paddingVertical", p: "padding", gap: "gap" }[match[1]];
827
+ frame[key] = points;
828
+ return true;
829
+ }
830
+ if (match = /^opacity-(\d+)$/.exec(utility)) return frame.opacity = Number(match[1]) / 100, true;
831
+ if ((match = /^font-(.+)$/.exec(utility)) && match[1] in FONT_WEIGHTS) return text.fontWeight = FONT_WEIGHTS[match[1]], true;
832
+ if ((match = /^tracking-(.+)$/.exec(utility)) && match[1] in TRACKING) return text.letterSpacing = TRACKING[match[1]], true;
833
+ if (utility === "uppercase" || utility === "lowercase" || utility === "capitalize") return text.textTransform = utility, true;
834
+ if (match = /^(from|to)-(.+)$/.exec(utility)) {
835
+ const value = colour(match[2], theme);
836
+ if (value === void 0) return false;
837
+ const stops = [...look3.gradient ?? ["transparent", "transparent"]];
838
+ stops[match[1] === "from" ? 0 : 1] = value;
839
+ look3.gradient = stops;
840
+ return true;
841
+ }
842
+ return false;
843
+ }
844
+ function finish(look3) {
845
+ for (const part of [look3, look3.disabled, look3.on]) {
846
+ if (part.text.letterSpacing !== void 0) part.text.letterSpacing = part.text.letterSpacing * (part.text.fontSize ?? look3.text.fontSize ?? 14);
847
+ }
848
+ return look3;
849
+ }
850
+ function nativeRecipe(config) {
851
+ return {
852
+ resolve(props, theme) {
853
+ const looks = {};
854
+ for (const [slot, classes] of Object.entries(classesFor(config, props))) {
855
+ const look3 = empty();
856
+ for (const cls of classes) if (!apply(look3, cls, theme)) look3.ignored.push(cls);
857
+ looks[slot] = finish(look3);
858
+ }
859
+ return looks;
860
+ }
861
+ };
862
+ }
863
+
864
+ // src/native/badge.tsx
865
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
866
+ var RECIPE = nativeRecipe(badgeRecipe);
867
+ function look(tone3, size, t) {
868
+ const { frame, text, dot } = RECIPE.resolve({ tone: tone3, size }, t).base;
869
+ const fg = text.color ?? t.textPrimary;
870
+ return {
871
+ bg: frame.backgroundColor ?? "transparent",
872
+ border: frame.borderColor ?? "transparent",
873
+ // The dot is the tone's colour, or the text's own (`bg-current` on the web).
874
+ dot: dot ?? fg,
875
+ paddingHorizontal: frame.paddingHorizontal ?? 8,
876
+ paddingVertical: frame.paddingVertical ?? 2,
877
+ text: { color: fg, fontSize: text.fontSize ?? 10, fontWeight: text.fontWeight, letterSpacing: text.letterSpacing, textTransform: text.textTransform }
878
+ };
686
879
  }
687
880
  function Badge({ tone: tone3 = "neutral", size = "sm", dot, pulse, style, children, ...props }) {
688
881
  const { theme } = useTheme();
689
- const colors = look(tone3, theme);
882
+ const colors = look(tone3, size, theme);
690
883
  const reduce = useReducedMotion();
691
884
  const [opacity] = React5.useState(() => new Animated.Value(1));
692
885
  React5.useEffect(() => {
@@ -707,51 +900,70 @@ function Badge({ tone: tone3 = "neutral", size = "sm", dot, pulse, style, childr
707
900
  Animated.View,
708
901
  {
709
902
  ...props,
710
- style: [styles5.root, size === "md" ? styles5.md : styles5.sm, { backgroundColor: colors.bg, borderColor: colors.border }, style],
903
+ style: [styles5.root, { paddingHorizontal: colors.paddingHorizontal, paddingVertical: colors.paddingVertical, backgroundColor: colors.bg, borderColor: colors.border }, style],
711
904
  children: [
712
905
  dot ? /* @__PURE__ */ jsx6(Animated.View, { "aria-hidden": true, style: [styles5.dot, { backgroundColor: colors.dot, opacity }] }) : null,
713
- typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx6(Text3, { style: [styles5.text, { color: colors.fg, fontSize: size === "md" ? 11 : 10 }], children }) : children
906
+ typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx6(Text3, { style: colors.text, children }) : children
714
907
  ]
715
908
  }
716
909
  );
717
910
  }
718
911
  var styles5 = StyleSheet5.create({
719
912
  root: { flexDirection: "row", alignItems: "center", alignSelf: "flex-start", gap: 4, borderRadius: 9999, borderWidth: 1 },
720
- sm: { paddingHorizontal: 8, paddingVertical: 2 },
721
- md: { paddingHorizontal: 10, paddingVertical: 4 },
722
- dot: { width: 6, height: 6, borderRadius: 3 },
723
- text: { fontWeight: "700", textTransform: "uppercase", letterSpacing: 0.8 }
913
+ dot: { width: 6, height: 6, borderRadius: 3 }
724
914
  });
725
915
 
726
916
  // src/native/button.tsx
727
917
  import * as React6 from "react";
728
918
  import { ActivityIndicator, Pressable as Pressable2, StyleSheet as StyleSheet6, View as View4 } from "react-native";
729
919
  import Svg2, { Defs as Defs2, LinearGradient as LinearGradient2, Rect, Stop as Stop2 } from "react-native-svg";
920
+
921
+ // src/button/recipe.ts
922
+ var buttonRecipe = defineRecipe({
923
+ base: "inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98] [&[data-loading]]:opacity-100",
924
+ variants: {
925
+ variant: {
926
+ primary: "bg-accent text-on-accent shadow-sm hover:bg-accent-hover",
927
+ // The brand's signature: accent → accent-2 (on-accent reads on both stops, tested in @krizaka/tokens).
928
+ gradient: "bg-linear-to-r from-accent to-accent-2 text-on-accent shadow-sm hover:brightness-110",
929
+ secondary: "border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3",
930
+ outline: "border border-border-default bg-transparent text-fg hover:border-accent hover:text-fg-accent",
931
+ ghost: "text-fg-secondary hover:bg-surface-2 hover:text-fg",
932
+ // The border and the tint carry the danger; the label stays the primary text role, legible on the tint at rest
933
+ // and hovered over every surface (`text-fg-danger` is for text set directly on a surface).
934
+ danger: "border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20"
935
+ },
936
+ size: { sm: "h-8 px-3 text-xs", md: "h-10 px-4 text-sm", lg: "h-12 px-6 text-sm", icon: "h-10 w-10" },
937
+ // `cut`: the Krizaka chamfer — 45° corners (CSS corner-shape, where supported; rounded elsewhere). The border, the
938
+ // focus ring and the hover follow the cut, unlike a clip-path.
939
+ shape: { rounded: "rounded-lg", pill: "rounded-full", cut: "rounded-[10px] [corner-shape:bevel]" }
940
+ },
941
+ defaultVariants: { variant: "secondary", size: "md", shape: "rounded" }
942
+ });
943
+
944
+ // src/native/button.tsx
730
945
  import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
731
- function look2(variant, t) {
732
- switch (variant) {
733
- case "primary":
734
- return { bg: t.accent, fg: t.onAccent, border: t.accent };
735
- case "gradient":
736
- return { bg: t.accent, fg: t.onAccent, border: "transparent", gradient: [t.accent, t.accent2] };
737
- case "outline":
738
- return { bg: "transparent", fg: t.textPrimary, border: t.borderDefault };
739
- case "ghost":
740
- return { bg: "transparent", fg: t.textSecondary, border: "transparent" };
741
- case "danger":
742
- return { bg: alpha(t.danger, 0.1), fg: t.textPrimary, border: alpha(t.danger, 0.5) };
743
- default:
744
- return { bg: t.surface2, fg: t.textPrimary, border: t.borderDefault };
745
- }
946
+ var RECIPE2 = nativeRecipe(buttonRecipe);
947
+ function look2(variant, size, t) {
948
+ const { frame, text, gradient } = RECIPE2.resolve({ variant, size }, t).base;
949
+ return {
950
+ // The brand's signature, accent → accent-2, is drawn over this fill; on-accent reads on both stops (tested in tokens).
951
+ bg: frame.backgroundColor ?? gradient?.[0] ?? "transparent",
952
+ fg: text.color ?? t.textPrimary,
953
+ border: frame.borderColor ?? "transparent",
954
+ gradient,
955
+ height: frame.height ?? 40,
956
+ paddingHorizontal: frame.paddingHorizontal ?? 16,
957
+ fontSize: text.fontSize ?? 14,
958
+ fontWeight: text.fontWeight
959
+ };
746
960
  }
747
- var HEIGHT = { sm: 32, md: 40, lg: 48 };
748
- var PADDING = { sm: 12, md: 16, lg: 24 };
749
961
  function useButton({ variant = "secondary", size = "md", shape = "rounded", loading, disabled }) {
750
962
  const { theme, radius: radius3 } = useTheme();
751
- const colors = look2(variant, theme);
963
+ const colors = look2(variant, size, theme);
752
964
  const inactive = Boolean(disabled || loading);
753
965
  const frame = (pressed) => ({
754
- height: HEIGHT[size],
966
+ height: colors.height,
755
967
  borderRadius: shape === "pill" ? radius3.full : radius3.sm,
756
968
  backgroundColor: colors.bg,
757
969
  borderColor: colors.border,
@@ -782,12 +994,12 @@ function Button({ label, icon, variant, size = "md", shape, loading = false, dis
782
994
  "aria-busy": loading,
783
995
  ...props,
784
996
  disabled: inactive,
785
- style: ({ pressed }) => [styles6.base, { paddingHorizontal: PADDING[size] }, frame(pressed), style],
997
+ style: ({ pressed }) => [styles6.base, { paddingHorizontal: colors.paddingHorizontal }, frame(pressed), style],
786
998
  children: [
787
999
  /* @__PURE__ */ jsx7(Fill, { colors, id: gradientId }),
788
1000
  /* @__PURE__ */ jsxs5(View4, { style: styles6.row, children: [
789
1001
  loading ? /* @__PURE__ */ jsx7(ActivityIndicator, { "aria-hidden": true, size: "small", color: colors.fg }) : icon,
790
- /* @__PURE__ */ jsx7(Txt, { variant: "label", numberOfLines: 1, style: { color: colors.fg, fontSize: size === "sm" ? 12 : 14 }, children: label })
1002
+ /* @__PURE__ */ jsx7(Txt, { variant: "label", numberOfLines: 1, style: { color: colors.fg, fontSize: colors.fontSize, fontWeight: colors.fontWeight }, children: label })
791
1003
  ] })
792
1004
  ]
793
1005
  }
@@ -796,7 +1008,7 @@ function Button({ label, icon, variant, size = "md", shape, loading = false, dis
796
1008
  function IconButton({ label, icon, variant, size = "md", shape, loading = false, disabled, style, ...props }) {
797
1009
  const { colors, inactive, frame } = useButton({ variant, size, shape, loading, disabled });
798
1010
  const gradientId = `kz-button-${React6.useId().replace(/:/g, "")}`;
799
- const side = HEIGHT[size];
1011
+ const side = colors.height;
800
1012
  return /* @__PURE__ */ jsxs5(
801
1013
  Pressable2,
802
1014
  {
@@ -822,14 +1034,43 @@ var styles6 = StyleSheet6.create({
822
1034
 
823
1035
  // src/native/card.tsx
824
1036
  import { Image as Image2, Pressable as Pressable3, StyleSheet as StyleSheet7, View as View5 } from "react-native";
1037
+
1038
+ // src/card/recipe.ts
1039
+ var cardRecipe = defineRecipe({
1040
+ slots: {
1041
+ root: "group relative flex flex-col overflow-hidden border border-border-default bg-surface-1 text-fg transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
1042
+ media: "relative overflow-hidden bg-media",
1043
+ image: "h-full w-full object-cover transition-transform duration-500 motion-safe:group-hover:scale-105",
1044
+ fallback: "flex h-full w-full items-center justify-center bg-linear-to-br from-accent/15 via-media to-accent-2/15 text-accent/60",
1045
+ overlay: "absolute z-10 flex items-center gap-1.5",
1046
+ body: "relative flex flex-1 flex-col gap-3",
1047
+ title: "line-clamp-1 text-sm font-semibold text-fg transition-colors group-hover:text-fg-accent",
1048
+ description: "line-clamp-2 text-xs text-fg-secondary",
1049
+ stat: "min-w-0",
1050
+ statLabel: "text-[10px] font-semibold uppercase tracking-wider text-fg-secondary",
1051
+ statValue: "font-display text-xl font-black tabular-nums text-fg",
1052
+ footer: "relative mt-auto flex items-center gap-2 border-t border-border-subtle pt-3 text-xs text-fg-secondary"
1053
+ },
1054
+ variants: {
1055
+ radius: { md: { root: "rounded-md" }, lg: { root: "rounded-lg" }, xl: { root: "rounded-xl" } },
1056
+ tone: { default: {}, elevated: { root: "bg-surface-2 shadow-md" }, glass: { root: "bg-surface-1/70 backdrop-blur-md" } },
1057
+ interactive: { true: { root: "kz-spotlight kz-lift hover:border-accent/50" } },
1058
+ padding: { none: { body: "p-0" }, sm: { body: "p-3" }, md: { body: "p-4" }, lg: { body: "p-6" } }
1059
+ },
1060
+ defaultVariants: { radius: "xl", tone: "default", padding: "md" }
1061
+ });
1062
+
1063
+ // src/native/card.tsx
825
1064
  import { jsx as jsx8 } from "react/jsx-runtime";
1065
+ var RECIPES = nativeRecipe(cardRecipe);
826
1066
  function CardRoot({ tone: tone3 = "default", radius: radius3 = "xl", onPress, style, ...props }) {
827
1067
  const { theme, radius: r } = useTheme();
1068
+ const { frame: look3 } = RECIPES.resolve({ tone: tone3 }, theme).root;
828
1069
  const frame = [
829
1070
  styles7.root,
830
1071
  {
831
- backgroundColor: tone3 === "elevated" ? theme.surface2 : theme.surface1,
832
- borderColor: theme.borderDefault,
1072
+ backgroundColor: look3.backgroundColor,
1073
+ borderColor: look3.borderColor,
833
1074
  borderRadius: r[radius3]
834
1075
  },
835
1076
  tone3 === "elevated" ? [styles7.shadow, { shadowColor: theme.scrimStrong }] : null
@@ -866,9 +1107,10 @@ var CORNER = {
866
1107
  function CardOverlay({ corner = "top-left", style, ...props }) {
867
1108
  return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.overlay, CORNER[corner], style] });
868
1109
  }
869
- var PADDING2 = { none: 0, sm: 12, md: 16, lg: 24 };
870
1110
  function CardBody({ padding = "md", style, ...props }) {
871
- return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.body, { padding: PADDING2[padding] }, style] });
1111
+ const { theme } = useTheme();
1112
+ const { frame } = RECIPES.resolve({ padding }, theme).body;
1113
+ return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.body, { padding: frame.padding }, style] });
872
1114
  }
873
1115
  function CardTitle({ numberOfLines = 1, ...props }) {
874
1116
  return /* @__PURE__ */ jsx8(Txt, { variant: "label", role: "heading", numberOfLines, ...props });
@@ -908,7 +1150,7 @@ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-run
908
1150
  var STATUS = { sending: "Sending", sent: "Sent", delivered: "Delivered", read: "Read", failed: "Not sent" };
909
1151
  function MessageBubble({ text, mine, time, status, showStatus, context, onRetry, grouped = "single", labels, style }) {
910
1152
  const { theme, radius: radius3 } = useTheme();
911
- const words = { ...STATUS, ...labels?.status };
1153
+ const words2 = { ...STATUS, ...labels?.status };
912
1154
  const failed = status === "failed";
913
1155
  const big = radius3.xl;
914
1156
  const tight = 6;
@@ -930,12 +1172,12 @@ function MessageBubble({ text, mine, time, status, showStatus, context, onRetry,
930
1172
  ]
931
1173
  }
932
1174
  );
933
- const name = [text, time, failed ? `${words.failed}. ${labels?.retry ?? ""}` : null].filter(Boolean).join(", ");
1175
+ const name = [text, time, failed ? `${words2.failed}. ${labels?.retry ?? ""}` : null].filter(Boolean).join(", ");
934
1176
  return /* @__PURE__ */ jsxs6(View6, { style: [styles8.row, mine ? styles8.mine : styles8.theirs, style], children: [
935
1177
  failed && onRetry ? /* @__PURE__ */ jsx9(Pressable4, { role: "button", "aria-label": name, onPress: onRetry, style: styles8.max, children: bubble }) : /* @__PURE__ */ jsx9(View6, { accessible: true, "aria-label": name, style: styles8.max, children: bubble }),
936
1178
  showStatus && status ? /* @__PURE__ */ jsxs6(View6, { style: styles8.status, children: [
937
1179
  status === "delivered" || status === "read" || status === "sent" ? /* @__PURE__ */ jsx9(Svg3, { width: 14, height: 14, viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx9(Path, { d: status === "sent" ? "M5 12.5l4.5 4.5L19 7.5" : "M2 12.5l4.5 4.5L16 7.5M9 15l2 2 9.5-9.5", fill: "none", stroke: status === "read" ? theme.accent : theme.textSecondary, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round" }) }) : null,
938
- /* @__PURE__ */ jsx9(Txt, { variant: "caption", tone: failed ? "danger" : "secondary", children: words[status] })
1180
+ /* @__PURE__ */ jsx9(Txt, { variant: "caption", tone: failed ? "danger" : "secondary", children: words2[status] })
939
1181
  ] }) : null
940
1182
  ] });
941
1183
  }
@@ -1109,28 +1351,48 @@ var styles9 = StyleSheet9.create({
1109
1351
  // src/native/chip.tsx
1110
1352
  import * as React9 from "react";
1111
1353
  import { Pressable as Pressable6, ScrollView, StyleSheet as StyleSheet10, Text as Text5, View as View8 } from "react-native";
1354
+
1355
+ // src/chip/recipe.ts
1356
+ var chipRecipe = defineRecipe({
1357
+ slots: {
1358
+ group: "flex flex-wrap items-center gap-2 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch",
1359
+ base: "inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-full border font-semibold transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg data-[state=on]:border-accent data-[state=on]:bg-accent-soft data-[state=on]:text-fg",
1360
+ remove: "-mr-1.5 inline-flex h-6 w-6 items-center justify-center rounded-full text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
1361
+ },
1362
+ variants: {
1363
+ size: { sm: { base: "h-7 px-3 text-xs" }, md: { base: "h-9 px-3.5 text-xs" } }
1364
+ },
1365
+ defaultVariants: { size: "md" }
1366
+ });
1367
+
1368
+ // src/native/chip.tsx
1112
1369
  import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
1113
1370
  var ChipGroupContext = React9.createContext(null);
1114
- function Label({ children, color, size }) {
1371
+ var RECIPE3 = nativeRecipe(chipRecipe);
1372
+ function Label({ children, color, fontSize }) {
1115
1373
  if (typeof children !== "string" && typeof children !== "number") return /* @__PURE__ */ jsx11(Fragment3, { children });
1116
- return /* @__PURE__ */ jsx11(Text5, { style: [styles10.label, { color, fontSize: size === "sm" ? 12 : 13 }], children });
1374
+ return /* @__PURE__ */ jsx11(Text5, { style: [styles10.label, { color, fontSize }], children });
1117
1375
  }
1118
1376
  function ChipBase(props) {
1119
1377
  const group = React9.useContext(ChipGroupContext);
1120
1378
  const { theme, radius: radius3 } = useTheme();
1121
1379
  const [own, setOwn] = React9.useState(props.removable ? false : props.defaultSelected ?? false);
1122
1380
  const size = props.size ?? group?.size ?? "md";
1381
+ const look3 = RECIPE3.resolve({ size }, theme).base;
1382
+ const fontSize = look3.text.fontSize ?? 12;
1123
1383
  const frame = (on2, pressed) => ({
1124
- height: size === "sm" ? 28 : 36,
1384
+ height: look3.frame.height,
1385
+ paddingHorizontal: look3.frame.paddingHorizontal,
1125
1386
  borderRadius: radius3.full,
1126
- borderColor: on2 ? theme.accent : theme.borderDefault,
1127
- backgroundColor: on2 ? theme.accentSoft : theme.surface1,
1387
+ borderColor: (on2 ? look3.on.frame.borderColor : look3.frame.borderColor) ?? "transparent",
1388
+ backgroundColor: (on2 ? look3.on.frame.backgroundColor : look3.frame.backgroundColor) ?? "transparent",
1128
1389
  opacity: pressed ? 0.85 : 1
1129
1390
  });
1391
+ const labelColor = (on2) => (on2 ? look3.on.text.color : look3.text.color) ?? theme.textPrimary;
1130
1392
  if (props.removable) {
1131
1393
  const { removable: _r2, removeLabel, onRemove, disabled: disabled2, size: _s2, style: style2, children: children2, ...rest2 } = props;
1132
1394
  return /* @__PURE__ */ jsxs8(View8, { ...rest2, style: [styles10.base, frame(false, false), disabled2 ? styles10.disabled : null, style2], children: [
1133
- /* @__PURE__ */ jsx11(Label, { color: theme.textSecondary, size, children: children2 }),
1395
+ /* @__PURE__ */ jsx11(Label, { color: labelColor(false), fontSize, children: children2 }),
1134
1396
  /* @__PURE__ */ jsx11(Pressable6, { role: "button", "aria-label": removeLabel, disabled: disabled2 ?? void 0, hitSlop: 10, onPress: onRemove, style: styles10.remove, children: /* @__PURE__ */ jsx11(Text5, { style: [styles10.cross, { color: theme.textSecondary }], children: "\xD7" }) })
1135
1397
  ] });
1136
1398
  }
@@ -1154,7 +1416,7 @@ function ChipBase(props) {
1154
1416
  disabled,
1155
1417
  onPress: press,
1156
1418
  style: ({ pressed }) => [styles10.base, frame(on, pressed), disabled ? styles10.disabled : null, style],
1157
- children: /* @__PURE__ */ jsx11(Label, { color: on ? theme.textPrimary : theme.textSecondary, size, children })
1419
+ children: /* @__PURE__ */ jsx11(Label, { color: labelColor(on), fontSize, children })
1158
1420
  }
1159
1421
  );
1160
1422
  }
@@ -1182,7 +1444,7 @@ function ChipGroup(props) {
1182
1444
  }
1183
1445
  var Chip = Object.assign(ChipBase, { Group: ChipGroup });
1184
1446
  var styles10 = StyleSheet10.create({
1185
- base: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 6, paddingHorizontal: 14, borderWidth: 1, alignSelf: "flex-start" },
1447
+ base: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 6, borderWidth: 1, alignSelf: "flex-start" },
1186
1448
  label: { fontWeight: "600" },
1187
1449
  remove: { marginRight: -6, width: 24, height: 24, alignItems: "center", justifyContent: "center" },
1188
1450
  cross: { fontSize: 16, lineHeight: 18, fontWeight: "700" },
@@ -1447,7 +1709,7 @@ function Countdown({ target, skewMs = 0, units, urgentBelowMs = 6e4, size = "md"
1447
1709
  };
1448
1710
  }, [urgent, reduce, opacity]);
1449
1711
  const color = urgent ? theme.dangerText : theme.textPrimary;
1450
- const text = parts.map(([value, unit]) => `${String(value).padStart(2, "0")}${unit}`).join(" ");
1712
+ const text = parts.map(([value, unit2]) => `${String(value).padStart(2, "0")}${unit2}`).join(" ");
1451
1713
  return /* @__PURE__ */ jsxs11(
1452
1714
  Animated4.View,
1453
1715
  {
@@ -1457,10 +1719,10 @@ function Countdown({ target, skewMs = 0, units, urgentBelowMs = 6e4, size = "md"
1457
1719
  style: [styles13.root, style],
1458
1720
  children: [
1459
1721
  showLabel ? /* @__PURE__ */ jsx14(Text8, { style: [styles13.label, { color: theme.textSecondary, fontSize: Math.max(11, Math.round(FONT[size] * 0.6)) }], children: label }) : null,
1460
- parts.map(([value, unit], i) => /* @__PURE__ */ jsxs11(Animated4.View, { style: [styles13.segment, urgent && i === parts.length - 1 ? { opacity } : null], children: [
1722
+ parts.map(([value, unit2], i) => /* @__PURE__ */ jsxs11(Animated4.View, { style: [styles13.segment, urgent && i === parts.length - 1 ? { opacity } : null], children: [
1461
1723
  /* @__PURE__ */ jsx14(Text8, { style: [styles13.value, { color, fontSize: FONT[size] }, fonts.display ? { fontFamily: fonts.display } : null], children: String(value).padStart(2, "0") }),
1462
- /* @__PURE__ */ jsx14(Text8, { style: [styles13.unit, { color: theme.textSecondary, fontSize: Math.round(FONT[size] / 2) }], children: unit })
1463
- ] }, unit))
1724
+ /* @__PURE__ */ jsx14(Text8, { style: [styles13.unit, { color: theme.textSecondary, fontSize: Math.round(FONT[size] / 2) }], children: unit2 })
1725
+ ] }, unit2))
1464
1726
  ]
1465
1727
  }
1466
1728
  );
@@ -2207,7 +2469,7 @@ function GoalGauge({ label, segments, value, valueText, mode = "fill", showLabel
2207
2469
  const { theme } = useTheme();
2208
2470
  const total = Math.max(1, Math.round(segments));
2209
2471
  const lit = Math.min(total, Math.max(0, Math.round(value ?? total)));
2210
- const words = valueText ?? `${lit} / ${total}`;
2472
+ const words2 = valueText ?? `${lit} / ${total}`;
2211
2473
  const arcade = variant === "arcade";
2212
2474
  return /* @__PURE__ */ jsxs19(
2213
2475
  View18,
@@ -2218,13 +2480,13 @@ function GoalGauge({ label, segments, value, valueText, mode = "fill", showLabel
2218
2480
  "aria-valuemin": 0,
2219
2481
  "aria-valuemax": total,
2220
2482
  "aria-valuenow": lit,
2221
- "aria-valuetext": words,
2483
+ "aria-valuetext": words2,
2222
2484
  ...props,
2223
2485
  style: [styles21.root, style],
2224
2486
  children: [
2225
2487
  showLabel ? /* @__PURE__ */ jsxs19(View18, { "aria-hidden": true, style: [styles21.head, arcade ? styles21.headArcade : null], children: [
2226
2488
  /* @__PURE__ */ jsx22(Txt, { variant: arcade ? "mono" : "caption", tone: "secondary", children: arcade ? label.toUpperCase() : label }),
2227
- arcade ? null : /* @__PURE__ */ jsx22(Txt, { variant: "caption", children: words })
2489
+ arcade ? null : /* @__PURE__ */ jsx22(Txt, { variant: "caption", children: words2 })
2228
2490
  ] }) : null,
2229
2491
  /* @__PURE__ */ jsx22(View18, { "aria-hidden": true, style: [styles21.cells, arcade ? [styles21.cellsArcade, { borderColor: theme.borderSubtle, backgroundColor: theme.surface1 }] : null], children: Array.from({ length: total }, (_, i) => {
2230
2492
  const on = i < lit;
@@ -2490,7 +2752,7 @@ function useMarkMotion(size, animated, spinMs = 3e4) {
2490
2752
  import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
2491
2753
  function KrizakaMark({ size = 48, animated = true, title, neutral }) {
2492
2754
  const { theme } = useTheme();
2493
- const { Animated: Animated27, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
2755
+ const { Animated: Animated28, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
2494
2756
  const id = useSvgId("kzm");
2495
2757
  const viewBox = size < 48 ? KRIZAKA.croppedViewBox : KRIZAKA.viewBox;
2496
2758
  const stroke = neutral ?? theme.textMuted;
@@ -2516,8 +2778,8 @@ function KrizakaMark({ size = 48, animated = true, title, neutral }) {
2516
2778
  /* @__PURE__ */ jsx25(Circle2, { cx: 200, cy: 200, r: KRIZAKA.ring.r, stroke, strokeWidth: KRIZAKA.ring.width, opacity: 0.35, fill: "none" }),
2517
2779
  /* @__PURE__ */ jsx25(Group, { transform: `translate(${KRIZAKA.offset} ${KRIZAKA.offset})`, children: /* @__PURE__ */ jsx25(Path6, { d: KRIZAKA.shield, stroke: `url(#${id}i)`, strokeWidth: KRIZAKA.stroke, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }) })
2518
2780
  ] }),
2519
- /* @__PURE__ */ jsx25(Animated27.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsx25(Svg8, { viewBox, style: layer, children: /* @__PURE__ */ jsx25(Circle2, { cx: 200, cy: 200, r: KRIZAKA.orbit.r, stroke, strokeWidth: KRIZAKA.orbit.width, strokeDasharray: KRIZAKA.orbit.dash, opacity: 0.6, fill: "none" }) }) }),
2520
- /* @__PURE__ */ jsx25(Animated27.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs22(Svg8, { viewBox, style: layer, children: [
2781
+ /* @__PURE__ */ jsx25(Animated28.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsx25(Svg8, { viewBox, style: layer, children: /* @__PURE__ */ jsx25(Circle2, { cx: 200, cy: 200, r: KRIZAKA.orbit.r, stroke, strokeWidth: KRIZAKA.orbit.width, strokeDasharray: KRIZAKA.orbit.dash, opacity: 0.6, fill: "none" }) }) }),
2782
+ /* @__PURE__ */ jsx25(Animated28.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs22(Svg8, { viewBox, style: layer, children: [
2521
2783
  /* @__PURE__ */ jsx25(Defs3, { children: blue }),
2522
2784
  /* @__PURE__ */ jsxs22(Group, { transform: `translate(${KRIZAKA.offset} ${KRIZAKA.offset})`, children: [
2523
2785
  dot(KRIZAKA.node),
@@ -2566,7 +2828,7 @@ var ORAZAKA = {
2566
2828
  import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
2567
2829
  function OrazakaMark({ size = 48, animated = true, title, neutral }) {
2568
2830
  const { theme } = useTheme();
2569
- const { Animated: Animated27, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
2831
+ const { Animated: Animated28, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
2570
2832
  const id = useSvgId("ozm");
2571
2833
  const viewBox = size < 48 ? ORAZAKA.croppedViewBox : ORAZAKA.viewBox;
2572
2834
  const stroke = neutral ?? theme.textMuted;
@@ -2582,11 +2844,11 @@ function OrazakaMark({ size = 48, animated = true, title, neutral }) {
2582
2844
  /* @__PURE__ */ jsx26(Circle3, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.orbit.r, stroke, strokeWidth: ORAZAKA.orbit.width, strokeDasharray: ORAZAKA.orbit.dash, opacity: 0.6, fill: "none" }),
2583
2845
  /* @__PURE__ */ jsx26(Circle3, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.ring.r, stroke, strokeWidth: ORAZAKA.ring.width, opacity: 0.35, fill: "none" })
2584
2846
  ] }),
2585
- /* @__PURE__ */ jsx26(Animated27.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs23(Svg9, { viewBox, style: layer, children: [
2847
+ /* @__PURE__ */ jsx26(Animated28.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs23(Svg9, { viewBox, style: layer, children: [
2586
2848
  /* @__PURE__ */ jsx26(Defs4, { children: gradient }),
2587
2849
  ORAZAKA.shards.map((d) => /* @__PURE__ */ jsx26(Path7, { d, fill, stroke: fill, strokeWidth: ORAZAKA.shardStroke, strokeLinejoin: "round" }, d))
2588
2850
  ] }) }),
2589
- /* @__PURE__ */ jsx26(Animated27.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs23(Svg9, { viewBox, style: layer, children: [
2851
+ /* @__PURE__ */ jsx26(Animated28.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs23(Svg9, { viewBox, style: layer, children: [
2590
2852
  /* @__PURE__ */ jsx26(Defs4, { children: gradient }),
2591
2853
  /* @__PURE__ */ jsx26(Circle3, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.core.r, fill }),
2592
2854
  /* @__PURE__ */ jsx26(Circle3, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.core.inner, fill: ORAZAKA.highlight })
@@ -2724,7 +2986,7 @@ var YASAKIA = {
2724
2986
  import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
2725
2987
  function YasakiaMark({ size = 48, animated = true, title, neutral }) {
2726
2988
  const { theme } = useTheme();
2727
- const { Animated: Animated27, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
2989
+ const { Animated: Animated28, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
2728
2990
  const id = useSvgId("yzm");
2729
2991
  const viewBox = size < 48 ? YASAKIA.croppedViewBox : YASAKIA.viewBox;
2730
2992
  const stroke = neutral ?? theme.textMuted;
@@ -2747,12 +3009,12 @@ function YasakiaMark({ size = 48, animated = true, title, neutral }) {
2747
3009
  i === 0 ? /* @__PURE__ */ jsx28(Path9, { d: `${v.body} ${v.tail}`, fill: YASAKIA.shade.color, opacity: YASAKIA.shade.opacity }) : null
2748
3010
  ] }, v.body))
2749
3011
  ] }),
2750
- /* @__PURE__ */ jsx28(Animated27.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs25(Svg11, { viewBox, style: layer, children: [
3012
+ /* @__PURE__ */ jsx28(Animated28.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs25(Svg11, { viewBox, style: layer, children: [
2751
3013
  /* @__PURE__ */ jsx28(Defs6, { children: gradient }),
2752
3014
  /* @__PURE__ */ jsx28(Circle5, { cx: YASAKIA.center, cy: YASAKIA.center, r: YASAKIA.orbit.r, stroke, strokeWidth: YASAKIA.orbit.width, strokeDasharray: YASAKIA.orbit.dash, opacity: 0.6, fill: "none" }),
2753
3015
  YASAKIA.pair.at.map(([cx, cy]) => /* @__PURE__ */ jsx28(Circle5, { cx, cy, r: YASAKIA.pair.r, fill }, cx))
2754
3016
  ] }) }),
2755
- /* @__PURE__ */ jsx28(Animated27.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs25(Svg11, { viewBox, style: layer, children: [
3017
+ /* @__PURE__ */ jsx28(Animated28.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs25(Svg11, { viewBox, style: layer, children: [
2756
3018
  /* @__PURE__ */ jsxs25(Defs6, { children: [
2757
3019
  gradient,
2758
3020
  /* @__PURE__ */ jsxs25(LinearGradient6, { id: `${id}l`, gradientUnits: "userSpaceOnUse", x1: 0, y1: YASAKIA.lens.y1, x2: 0, y2: YASAKIA.lens.y2, children: [
@@ -2808,7 +3070,7 @@ var YORORIS = {
2808
3070
  import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
2809
3071
  function YororisMark({ size = 48, animated = true, title, neutral }) {
2810
3072
  const { theme } = useTheme();
2811
- const { Animated: Animated27, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated, 36e3);
3073
+ const { Animated: Animated28, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated, 36e3);
2812
3074
  const id = useSvgId("yrm");
2813
3075
  const viewBox = size < 48 ? YORORIS.croppedViewBox : YORORIS.viewBox;
2814
3076
  const stroke = neutral ?? theme.textMuted;
@@ -2829,12 +3091,12 @@ function YororisMark({ size = 48, animated = true, title, neutral }) {
2829
3091
  YORORIS.leaves.map((d) => /* @__PURE__ */ jsx29(Path10, { d, fill }, d)),
2830
3092
  /* @__PURE__ */ jsx29(Path10, { d: YORORIS.veins, stroke: YORORIS.vein.color, strokeOpacity: YORORIS.vein.opacity, strokeWidth: YORORIS.vein.width, strokeLinecap: "round", strokeDasharray: YORORIS.vein.dash, fill: "none" })
2831
3093
  ] }),
2832
- /* @__PURE__ */ jsx29(Animated27.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs26(Svg12, { viewBox, style: layer, children: [
3094
+ /* @__PURE__ */ jsx29(Animated28.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs26(Svg12, { viewBox, style: layer, children: [
2833
3095
  /* @__PURE__ */ jsx29(Defs7, { children: gradient }),
2834
3096
  /* @__PURE__ */ jsx29(Circle6, { cx: YORORIS.center, cy: YORORIS.center, r: YORORIS.orbit.r, stroke, strokeWidth: YORORIS.orbit.width, strokeDasharray: YORORIS.orbit.dash, opacity: 0.6, fill: "none" }),
2835
3097
  /* @__PURE__ */ jsx29(Circle6, { cx: YORORIS.moment.at[0], cy: YORORIS.moment.at[1], r: YORORIS.moment.r, fill })
2836
3098
  ] }) }),
2837
- /* @__PURE__ */ jsx29(Animated27.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs26(Svg12, { viewBox, style: layer, children: [
3099
+ /* @__PURE__ */ jsx29(Animated28.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs26(Svg12, { viewBox, style: layer, children: [
2838
3100
  /* @__PURE__ */ jsx29(Defs7, { children: /* @__PURE__ */ jsx29(LinearGradient7, { id: `${id}c`, x1: "50%", y1: "100%", x2: "50%", y2: "0%", children: YORORIS.coreGradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx29(Stop7, { offset, stopColor: color }, offset)) }) }),
2839
3101
  /* @__PURE__ */ jsx29(Circle6, { cx: YORORIS.core.cx, cy: YORORIS.core.cy, r: YORORIS.core.r, fill: `url(#${id}c)` }),
2840
3102
  /* @__PURE__ */ jsx29(Circle6, { cx: YORORIS.core.cx, cy: YORORIS.core.cy, r: YORORIS.core.inner, fill: YORORIS.highlight })
@@ -2919,10 +3181,10 @@ function Loader({ label, status = "loading", successLabel, errorLabel, value, et
2919
3181
  };
2920
3182
  }, [waiting, status, endDuration]);
2921
3183
  const phase = waiting ? "loading" : ending;
2922
- const words = phase === "success" ? successLabel ?? label : phase === "error" ? errorLabel ?? label : label;
3184
+ const words2 = phase === "success" ? successLabel ?? label : phase === "error" ? errorLabel ?? label : label;
2923
3185
  React22.useEffect(() => {
2924
- if (phase) AccessibilityInfo7.announceForAccessibility(words);
2925
- }, [phase, words]);
3186
+ if (phase) AccessibilityInfo7.announceForAccessibility(words2);
3187
+ }, [phase, words2]);
2926
3188
  if (!phase) return null;
2927
3189
  const known = phase === "loading" && typeof value === "number" && Number.isFinite(value);
2928
3190
  const detail = phase === "loading" ? [known ? `${Math.round(Math.min(1, Math.max(0, value)) * 100)} %` : null, eta].filter(Boolean).join(" \xB7 ") : "";
@@ -2930,11 +3192,11 @@ function Loader({ label, status = "loading", successLabel, errorLabel, value, et
2930
3192
  const box = /* @__PURE__ */ jsxs27(View26, { style: [stacked ? styles24.stacked : styles24.inline, variant === "overlay" ? { backgroundColor: alpha(theme.surface1, 0.92), borderColor: theme.borderDefault, borderRadius: radius3.lg, ...styles24.card } : null], children: [
2931
3193
  product && phase === "loading" ? /* @__PURE__ */ jsx31(ProductMark, { id: product, size: GLYPH[variant], animated: true }) : /* @__PURE__ */ jsx31(LoaderGlyph, { state: phase, value: known ? value : null, size: GLYPH[variant] }),
2932
3194
  /* @__PURE__ */ jsxs27(View26, { style: stacked ? styles24.center : styles24.text, children: [
2933
- /* @__PURE__ */ jsx31(Txt, { variant: variant === "page" ? "title" : "label", style: stacked ? styles24.centered : null, children: words }),
3195
+ /* @__PURE__ */ jsx31(Txt, { variant: variant === "page" ? "title" : "label", style: stacked ? styles24.centered : null, children: words2 }),
2934
3196
  detail ? /* @__PURE__ */ jsx31(Txt, { variant: "caption", tone: "secondary", style: stacked ? styles24.centered : null, children: detail }) : null
2935
3197
  ] })
2936
3198
  ] });
2937
- const a11y = { accessible: true, role: "progressbar", "aria-label": words, "aria-busy": phase === "loading", accessibilityLiveRegion: "polite" };
3199
+ const a11y = { accessible: true, role: "progressbar", "aria-label": words2, "aria-busy": phase === "loading", accessibilityLiveRegion: "polite" };
2938
3200
  if (variant === "overlay" || variant === "page")
2939
3201
  return /* @__PURE__ */ jsx31(View26, { ...a11y, style: [StyleSheet24.absoluteFill, styles24.cover, variant === "page" ? { backgroundColor: alpha(theme.surface0, 0.86) } : null, style], children: box });
2940
3202
  return /* @__PURE__ */ jsx31(View26, { ...a11y, style: [variant === "block" ? styles24.block : null, style], children: box });
@@ -3321,9 +3583,9 @@ function Meter({ label, value = 0, min = 0, max = 100, valueText, thresholds, op
3321
3583
  const ratio = Math.min(1, Math.max(0, (value - min) / span));
3322
3584
  const level = !thresholds ? "ok" : ratio >= thresholds.high ? optimum === "low" ? "danger" : "success" : ratio >= thresholds.low ? "warning" : optimum === "low" ? "success" : "danger";
3323
3585
  const tone3 = { ok: theme.accent, success: theme.success, warning: theme.warning, danger: theme.danger }[level];
3324
- const words = valueText ?? `${Math.round(ratio * 100)} %`;
3586
+ const words2 = valueText ?? `${Math.round(ratio * 100)} %`;
3325
3587
  const shares = (parts ?? []).map((p, i) => ({ ...p, color: partColor(theme, i), ratio: Math.min(1, Math.max(0, p.value / span)), words: p.valueText ?? `${Math.round(p.value / span * 100)} %` }));
3326
- const a11y = parts ? { role: "group", "aria-label": `${label}: ${shares.map((p) => `${p.label} ${p.words}`).join(", ")}` } : { role: "meter", "aria-label": label, "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": Math.min(max, Math.max(min, value)), "aria-valuetext": words };
3588
+ const a11y = parts ? { role: "group", "aria-label": `${label}: ${shares.map((p) => `${p.label} ${p.words}`).join(", ")}` } : { role: "meter", "aria-label": label, "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": Math.min(max, Math.max(min, value)), "aria-valuetext": words2 };
3327
3589
  const legend = parts ? /* @__PURE__ */ jsx35(View30, { style: styles27.legend, "aria-hidden": true, children: shares.map((p, i) => /* @__PURE__ */ jsxs31(View30, { style: styles27.legendItem, children: [
3328
3590
  /* @__PURE__ */ jsx35(View30, { style: [styles27.swatch, { backgroundColor: p.color }] }),
3329
3591
  /* @__PURE__ */ jsx35(Txt, { variant: "caption", children: p.label }),
@@ -3353,7 +3615,7 @@ function Meter({ label, value = 0, min = 0, max = 100, valueText, thresholds, op
3353
3615
  return /* @__PURE__ */ jsxs31(View30, { accessible: true, ...a11y, style: [styles27.root, style], children: [
3354
3616
  showLabel ? /* @__PURE__ */ jsxs31(View30, { style: styles27.header, "aria-hidden": true, children: [
3355
3617
  /* @__PURE__ */ jsx35(Txt, { variant: "caption", numberOfLines: 1, style: styles27.caption, children: label }),
3356
- !parts ? /* @__PURE__ */ jsx35(Txt, { variant: "caption", tone: "secondary", children: words }) : null
3618
+ !parts ? /* @__PURE__ */ jsx35(Txt, { variant: "caption", tone: "secondary", children: words2 }) : null
3357
3619
  ] }) : null,
3358
3620
  /* @__PURE__ */ jsx35(View30, { style: [styles27.track, { height: THICK[size], backgroundColor: theme.surface3 }], children: parts ? shares.map((p, i) => /* @__PURE__ */ jsx35(View30, { style: { width: `${p.ratio * 100}%`, backgroundColor: p.color } }, i)) : /* @__PURE__ */ jsx35(View30, { style: [styles27.fill, { width: `${ratio * 100}%`, backgroundColor: tone3 }] }) }),
3359
3621
  legend
@@ -3779,7 +4041,7 @@ import * as React31 from "react";
3779
4041
  import { Animated as Animated17, StyleSheet as StyleSheet33, View as View37 } from "react-native";
3780
4042
  import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
3781
4043
  var ratioOf = (value, max = 100) => Math.min(1, Math.max(0, value / (max || 1)));
3782
- function Bar({ label, ratio, words, animated, delay }) {
4044
+ function Bar({ label, ratio, words: words2, animated, delay }) {
3783
4045
  const { theme } = useTheme();
3784
4046
  const t = useEntrance(animated, delay, 900);
3785
4047
  const [width, setWidth] = React31.useState(0);
@@ -3793,7 +4055,7 @@ function Bar({ label, ratio, words, animated, delay }) {
3793
4055
  "aria-valuemin": 0,
3794
4056
  "aria-valuemax": 100,
3795
4057
  "aria-valuenow": Math.round(ratio * 100),
3796
- "aria-valuetext": words,
4058
+ "aria-valuetext": words2,
3797
4059
  onLayout: (e) => setWidth(e.nativeEvent.layout.width),
3798
4060
  style: [styles33.track, { backgroundColor: theme.surface3 }],
3799
4061
  children: /* @__PURE__ */ jsx43(Animated17.View, { style: [styles33.fill, { width: `${ratio * 100}%`, backgroundColor: theme.accent, transform: [{ translateX }] }] })
@@ -3816,13 +4078,13 @@ function ProfileCard({ visual, name, statLabel, value = 100, valueText, stats, c
3816
4078
  statLabel ? /* @__PURE__ */ jsx43(Bar, { label: statLabel, ratio, words: valueText ?? `${Math.round(ratio * 100)} %`, animated, delay: 200 }) : null,
3817
4079
  stats?.map((s, i) => {
3818
4080
  const r = ratioOf(s.value, s.max);
3819
- const words = s.valueText ?? `${Math.round(r * 100)} %`;
4081
+ const words2 = s.valueText ?? `${Math.round(r * 100)} %`;
3820
4082
  return /* @__PURE__ */ jsxs38(View37, { style: styles33.stat, children: [
3821
4083
  /* @__PURE__ */ jsxs38(View37, { "aria-hidden": true, style: styles33.statHead, children: [
3822
4084
  /* @__PURE__ */ jsx43(Txt, { variant: "caption", tone: "secondary", children: s.label }),
3823
- /* @__PURE__ */ jsx43(Txt, { variant: "caption", children: words })
4085
+ /* @__PURE__ */ jsx43(Txt, { variant: "caption", children: words2 })
3824
4086
  ] }),
3825
- /* @__PURE__ */ jsx43(Bar, { label: s.label, ratio: r, words, animated, delay: 320 + i * 120 })
4087
+ /* @__PURE__ */ jsx43(Bar, { label: s.label, ratio: r, words: words2, animated, delay: 320 + i * 120 })
3826
4088
  ] }, s.label);
3827
4089
  }),
3828
4090
  caption ? /* @__PURE__ */ jsx43(Txt, { variant: "caption", tone: "secondary", style: styles33.caption, children: caption }) : null,
@@ -4147,6 +4409,7 @@ function Screen({ header, footer, children, scroll = true, keyboard = true, padd
4147
4409
  var styles37 = StyleSheet37.create({ flex: { flex: 1 } });
4148
4410
 
4149
4411
  // src/native/search-field.tsx
4412
+ import { useDebouncedCallback } from "@krizaka/pacer/react";
4150
4413
  import * as React35 from "react";
4151
4414
  import { Pressable as Pressable19, StyleSheet as StyleSheet38, TextInput as TextInput6, View as View42 } from "react-native";
4152
4415
  import Svg22, { Circle as Circle12, Path as Path18 } from "react-native-svg";
@@ -4157,13 +4420,12 @@ function SearchField({ label, value, defaultValue = "", onValueChange, onSearch,
4157
4420
  const { theme, radius: radius3 } = useTheme();
4158
4421
  const [own, setOwn] = React35.useState(defaultValue);
4159
4422
  const query = value ?? own;
4160
- const timer2 = React35.useRef(void 0);
4161
- React35.useEffect(() => () => clearTimeout(timer2.current), []);
4423
+ const search = useDebouncedCallback((next) => onSearch?.(next), debounce);
4162
4424
  const change = (next) => {
4163
4425
  if (value === void 0) setOwn(next);
4164
4426
  onValueChange?.(next);
4165
- clearTimeout(timer2.current);
4166
- if (onSearch) timer2.current = setTimeout(() => onSearch(next), debounce);
4427
+ search.cancel();
4428
+ if (onSearch) search(next);
4167
4429
  };
4168
4430
  const field = /* @__PURE__ */ jsxs43(View42, { style: [styles38.frame, { borderRadius: radius3.md, borderColor: theme.borderDefault, backgroundColor: theme.surface2 }, style], children: [
4169
4431
  /* @__PURE__ */ jsxs43(Svg22, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: theme.textSecondary, strokeWidth: 2, strokeLinecap: "round", "aria-hidden": true, children: [
@@ -4185,7 +4447,7 @@ function SearchField({ label, value, defaultValue = "", onValueChange, onSearch,
4185
4447
  clearButtonMode: "never",
4186
4448
  onChangeText: change,
4187
4449
  onSubmitEditing: () => {
4188
- clearTimeout(timer2.current);
4450
+ search.cancel();
4189
4451
  onSearch?.(query);
4190
4452
  onSubmit?.(query);
4191
4453
  },
@@ -4275,10 +4537,125 @@ var styles39 = StyleSheet39.create({
4275
4537
  disabled: { opacity: 0.4 }
4276
4538
  });
4277
4539
 
4278
- // src/native/skeleton.tsx
4540
+ // src/native/showcase.tsx
4279
4541
  import * as React36 from "react";
4280
- import { Animated as Animated21 } from "react-native";
4281
- import { jsx as jsx50 } from "react/jsx-runtime";
4542
+ import { Animated as Animated21, AppState, Easing as Easing12, FlatList, Pressable as Pressable21, StyleSheet as StyleSheet40, View as View44 } from "react-native";
4543
+ import Svg23, { Path as Path19 } from "react-native-svg";
4544
+ import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
4545
+ var showcaseLabels = {
4546
+ previous: "Previous slide",
4547
+ next: "Next slide",
4548
+ pause: "Pause the slideshow",
4549
+ play: "Play the slideshow",
4550
+ goTo: (n) => `Go to slide ${n}`,
4551
+ counter: (n, total) => `Slide ${n} of ${total}`,
4552
+ slide: (n, total) => `${n} of ${total}`
4553
+ };
4554
+ function Showcase({ label, items: items2, getId, renderItem, getTitle, interval = 6e3, autoplay = true, loop = true, onIndexChange, labels = showcaseLabels, style }) {
4555
+ const { theme } = useTheme();
4556
+ const reduced = useReducedMotion();
4557
+ const total = items2.length;
4558
+ const [current, setCurrent] = React36.useState(0);
4559
+ const [width, setWidth] = React36.useState(0);
4560
+ const [paused, setPaused] = React36.useState(false);
4561
+ const [dragging, setDragging] = React36.useState(false);
4562
+ const [background, setBackground] = React36.useState(false);
4563
+ const [announce, setAnnounce] = React36.useState(false);
4564
+ const list = React36.useRef(null);
4565
+ const [fill] = React36.useState(() => new Animated21.Value(0));
4566
+ const progress = React36.useRef(0);
4567
+ React36.useEffect(() => {
4568
+ const id = fill.addListener(({ value }) => {
4569
+ progress.current = value;
4570
+ });
4571
+ const subscription = AppState.addEventListener("change", (state) => setBackground(state !== "active"));
4572
+ return () => {
4573
+ fill.removeListener(id);
4574
+ subscription.remove();
4575
+ };
4576
+ }, [fill]);
4577
+ const go = (to, user) => {
4578
+ if (total === 0) return;
4579
+ const next = loop ? (to + total) % total : Math.min(Math.max(to, 0), total - 1);
4580
+ if (next === current) return;
4581
+ setAnnounce(user);
4582
+ setCurrent(next);
4583
+ list.current?.scrollToOffset({ offset: next * width, animated: !reduced });
4584
+ onIndexChange?.(next, user);
4585
+ };
4586
+ const playing = autoplay && !reduced && total > 1;
4587
+ const running = playing && !paused && !dragging && !background && !(!loop && current === total - 1);
4588
+ React36.useEffect(() => {
4589
+ fill.setValue(0);
4590
+ progress.current = 0;
4591
+ }, [current, fill]);
4592
+ React36.useEffect(() => {
4593
+ if (!running) return;
4594
+ const animation = Animated21.timing(fill, { toValue: 1, duration: Math.max(1, interval * (1 - progress.current)), easing: Easing12.linear, useNativeDriver: false });
4595
+ animation.start(({ finished }) => {
4596
+ if (finished) go(current + 1, false);
4597
+ });
4598
+ return () => animation.stop();
4599
+ }, [running, current, interval]);
4600
+ const item = items2[current];
4601
+ const title = item !== void 0 ? getTitle?.(item) : void 0;
4602
+ const control = [styles40.control, { borderColor: theme.borderDefault, backgroundColor: theme.surface1 }];
4603
+ const icon = (d) => /* @__PURE__ */ jsx50(Svg23, { width: 16, height: 16, viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx50(Path19, { d, stroke: theme.textSecondary, strokeWidth: 2.2, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) });
4604
+ return /* @__PURE__ */ jsxs44(View44, { role: "group", "aria-label": label, style: [styles40.root, style], children: [
4605
+ /* @__PURE__ */ jsx50(View44, { "aria-live": announce ? "polite" : "off", onLayout: (e) => setWidth(e.nativeEvent.layout.width), children: /* @__PURE__ */ jsx50(
4606
+ FlatList,
4607
+ {
4608
+ ref: list,
4609
+ horizontal: true,
4610
+ pagingEnabled: true,
4611
+ focusable: true,
4612
+ showsHorizontalScrollIndicator: false,
4613
+ data: items2,
4614
+ keyExtractor: getId,
4615
+ getItemLayout: (_, index) => ({ length: width, offset: width * index, index }),
4616
+ onScrollBeginDrag: () => setDragging(true),
4617
+ onScrollEndDrag: () => setDragging(false),
4618
+ onMomentumScrollEnd: (e) => {
4619
+ const next = Math.round(e.nativeEvent.contentOffset.x / Math.max(width, 1));
4620
+ if (next !== current && next >= 0 && next < total) {
4621
+ setAnnounce(true);
4622
+ setCurrent(next);
4623
+ onIndexChange?.(next, true);
4624
+ }
4625
+ },
4626
+ renderItem: ({ item: slide, index }) => /* @__PURE__ */ jsx50(View44, { role: "group", "aria-label": labels.slide(index + 1, total), style: { width }, children: Math.abs(index - current) <= 1 ? renderItem(slide, { index, active: index === current }) : null })
4627
+ }
4628
+ ) }),
4629
+ /* @__PURE__ */ jsx50(View44, { style: styles40.segments, children: items2.map((slide, i) => /* @__PURE__ */ jsx50(Pressable21, { role: "button", "aria-label": labels.goTo(i + 1, total), "aria-current": i === current ? true : void 0, onPress: () => go(i, true), style: styles40.segment, children: /* @__PURE__ */ jsxs44(View44, { style: [styles40.track, { backgroundColor: theme.surface3 }], children: [
4630
+ i < current || i === current && !playing ? /* @__PURE__ */ jsx50(View44, { style: [StyleSheet40.absoluteFill, { backgroundColor: theme.accent }] }) : null,
4631
+ i === current && playing ? /* @__PURE__ */ jsx50(Animated21.View, { style: [styles40.fill, { backgroundColor: theme.accent, width: fill.interpolate({ inputRange: [0, 1], outputRange: ["0%", "100%"] }) }] }) : null
4632
+ ] }) }, getId(slide))) }),
4633
+ /* @__PURE__ */ jsxs44(View44, { style: styles40.bar, children: [
4634
+ /* @__PURE__ */ jsxs44(Txt, { variant: "caption", tone: "secondary", numberOfLines: 1, style: styles40.counter, children: [
4635
+ title ? `${title} \xB7 ` : "",
4636
+ labels.counter(current + 1, total)
4637
+ ] }),
4638
+ /* @__PURE__ */ jsx50(Pressable21, { role: "button", "aria-label": labels.previous, disabled: !loop && current === 0, hitSlop: 6, onPress: () => go(current - 1, true), style: control, children: icon("M15 5l-7 7 7 7") }),
4639
+ playing ? /* @__PURE__ */ jsx50(Pressable21, { role: "button", "aria-label": paused ? labels.play : labels.pause, hitSlop: 6, onPress: () => setPaused(!paused), style: control, children: icon(paused ? "M8 5.5v13l10-6.5Z" : "M8 5v14M16 5v14") }) : null,
4640
+ /* @__PURE__ */ jsx50(Pressable21, { role: "button", "aria-label": labels.next, disabled: !loop && current === total - 1, hitSlop: 6, onPress: () => go(current + 1, true), style: control, children: icon("M9 5l7 7-7 7") })
4641
+ ] })
4642
+ ] });
4643
+ }
4644
+ var styles40 = StyleSheet40.create({
4645
+ root: { gap: 8 },
4646
+ segments: { flexDirection: "row", gap: 4 },
4647
+ segment: { flex: 1, height: 24, justifyContent: "center" },
4648
+ track: { height: 4, borderRadius: 2, overflow: "hidden" },
4649
+ fill: { position: "absolute", left: 0, top: 0, bottom: 0 },
4650
+ bar: { flexDirection: "row", alignItems: "center", gap: 8 },
4651
+ counter: { flex: 1 },
4652
+ control: { width: 36, height: 36, borderRadius: 18, borderWidth: 1, alignItems: "center", justifyContent: "center" }
4653
+ });
4654
+
4655
+ // src/native/skeleton.tsx
4656
+ import * as React37 from "react";
4657
+ import { Animated as Animated22 } from "react-native";
4658
+ import { jsx as jsx51 } from "react/jsx-runtime";
4282
4659
  var SHAPE = {
4283
4660
  text: { width: "100%", height: 12, radius: 4 },
4284
4661
  circle: { width: 40, height: 40, radius: 9999 },
@@ -4287,13 +4664,13 @@ var SHAPE = {
4287
4664
  function Skeleton({ shape = "text", width, height, style, testID }) {
4288
4665
  const { theme } = useTheme();
4289
4666
  const reduce = useReducedMotion();
4290
- const [opacity] = React36.useState(() => new Animated21.Value(1));
4291
- React36.useEffect(() => {
4667
+ const [opacity] = React37.useState(() => new Animated22.Value(1));
4668
+ React37.useEffect(() => {
4292
4669
  if (reduce) return;
4293
- const loop = Animated21.loop(
4294
- Animated21.sequence([
4295
- Animated21.timing(opacity, { toValue: 0.5, duration: 900, useNativeDriver: true }),
4296
- Animated21.timing(opacity, { toValue: 1, duration: 900, useNativeDriver: true })
4670
+ const loop = Animated22.loop(
4671
+ Animated22.sequence([
4672
+ Animated22.timing(opacity, { toValue: 0.5, duration: 900, useNativeDriver: true }),
4673
+ Animated22.timing(opacity, { toValue: 1, duration: 900, useNativeDriver: true })
4297
4674
  ])
4298
4675
  );
4299
4676
  loop.start();
@@ -4304,8 +4681,8 @@ function Skeleton({ shape = "text", width, height, style, testID }) {
4304
4681
  }, [reduce, opacity]);
4305
4682
  const s = SHAPE[shape];
4306
4683
  const side = shape === "circle" ? width ?? height ?? s.width : void 0;
4307
- return /* @__PURE__ */ jsx50(
4308
- Animated21.View,
4684
+ return /* @__PURE__ */ jsx51(
4685
+ Animated22.View,
4309
4686
  {
4310
4687
  testID,
4311
4688
  "aria-hidden": true,
@@ -4318,10 +4695,10 @@ function Skeleton({ shape = "text", width, height, style, testID }) {
4318
4695
  }
4319
4696
 
4320
4697
  // src/native/slider.tsx
4321
- import * as React37 from "react";
4322
- import { PanResponder as PanResponder2, StyleSheet as StyleSheet40, Text as Text17, View as View44 } from "react-native";
4323
- import Svg23, { Defs as Defs11, LinearGradient as LinearGradient11, Rect as Rect4, Stop as Stop11 } from "react-native-svg";
4324
- import { jsx as jsx51, jsxs as jsxs44 } from "react/jsx-runtime";
4698
+ import * as React38 from "react";
4699
+ import { PanResponder as PanResponder2, StyleSheet as StyleSheet41, Text as Text17, View as View45 } from "react-native";
4700
+ import Svg24, { Defs as Defs11, LinearGradient as LinearGradient11, Rect as Rect4, Stop as Stop11 } from "react-native-svg";
4701
+ import { jsx as jsx52, jsxs as jsxs45 } from "react/jsx-runtime";
4325
4702
  var THUMB = 26;
4326
4703
  var toArray = (v) => v === void 0 ? void 0 : typeof v === "number" ? [v] : [...v];
4327
4704
  function Slider({
@@ -4347,20 +4724,20 @@ function Slider({
4347
4724
  const { theme, radius: radius3, haptic } = useTheme();
4348
4725
  const range = Array.isArray(value ?? defaultValue);
4349
4726
  const vertical = orientation === "vertical";
4350
- const [inner, setInner] = React37.useState(() => toArray(defaultValue) ?? [min]);
4727
+ const [inner, setInner] = React38.useState(() => toArray(defaultValue) ?? [min]);
4351
4728
  const current = toArray(value) ?? inner;
4352
- const [length, setLength] = React37.useState(0);
4353
- const [dragging, setDragging] = React37.useState(null);
4729
+ const [length, setLength] = React38.useState(0);
4730
+ const [dragging, setDragging] = React38.useState(null);
4354
4731
  const gradientId = useSvgId("kzs");
4355
4732
  const out = (next) => range ? [next[0], next[1]] : next[0];
4356
4733
  const snap = (v) => Math.min(max, Math.max(min, Math.round((v - min) / step) * step + min));
4357
4734
  const pct = (v) => (v - min) / (max - min || 1);
4358
- const live = React37.useRef({ current, length, vertical, disabled });
4359
- React37.useLayoutEffect(() => {
4735
+ const live = React38.useRef({ current, length, vertical, disabled });
4736
+ React38.useLayoutEffect(() => {
4360
4737
  live.current = { current, length, vertical, disabled };
4361
4738
  });
4362
- const active = React37.useRef(0);
4363
- const start = React37.useRef(0);
4739
+ const active = React38.useRef(0);
4740
+ const start = React38.useRef(0);
4364
4741
  const set = (next) => {
4365
4742
  if (value === void 0) setInner(next);
4366
4743
  onValueChange?.(out(next));
@@ -4381,11 +4758,11 @@ function Slider({
4381
4758
  return min + p * (max - min);
4382
4759
  };
4383
4760
  const commit = () => onValueCommit?.(out(live.current.current));
4384
- const handlers = React37.useRef({ move, at, commit });
4385
- React37.useLayoutEffect(() => {
4761
+ const handlers = React38.useRef({ move, at, commit });
4762
+ React38.useLayoutEffect(() => {
4386
4763
  handlers.current = { move, at, commit };
4387
4764
  });
4388
- const [responder] = React37.useState(
4765
+ const [responder] = React38.useState(
4389
4766
  () => PanResponder2.create({
4390
4767
  onStartShouldSetPanResponder: () => !live.current.disabled,
4391
4768
  onMoveShouldSetPanResponder: () => !live.current.disabled,
@@ -4413,24 +4790,24 @@ function Slider({
4413
4790
  const along = (p) => vertical ? { bottom: p * length } : { left: p * length };
4414
4791
  const onLayout = (e) => setLength(vertical ? e.nativeEvent.layout.height : e.nativeEvent.layout.width);
4415
4792
  const fill = vertical ? { bottom: pct(lo) * length, height: (pct(hi) - pct(lo)) * length, left: 0, right: 0 } : { left: pct(lo) * length, width: (pct(hi) - pct(lo)) * length, top: 0, bottom: 0 };
4416
- return /* @__PURE__ */ jsxs44(View44, { style: [styles40.root, vertical ? styles40.rootVertical : null, disabled ? styles40.disabled : null, style], children: [
4417
- showLabel ? /* @__PURE__ */ jsxs44(View44, { style: styles40.header, children: [
4418
- /* @__PURE__ */ jsx51(Text17, { style: [styles40.label, { color: theme.textSecondary }], children: label }),
4419
- /* @__PURE__ */ jsx51(Text17, { "aria-hidden": true, style: [styles40.value, { color: theme.textSecondary }], children: current.map(formatValue).join(" \u2013 ") })
4793
+ return /* @__PURE__ */ jsxs45(View45, { style: [styles41.root, vertical ? styles41.rootVertical : null, disabled ? styles41.disabled : null, style], children: [
4794
+ showLabel ? /* @__PURE__ */ jsxs45(View45, { style: styles41.header, children: [
4795
+ /* @__PURE__ */ jsx52(Text17, { style: [styles41.label, { color: theme.textSecondary }], children: label }),
4796
+ /* @__PURE__ */ jsx52(Text17, { "aria-hidden": true, style: [styles41.value, { color: theme.textSecondary }], children: current.map(formatValue).join(" \u2013 ") })
4420
4797
  ] }) : null,
4421
- /* @__PURE__ */ jsxs44(View44, { ...responder.panHandlers, style: vertical ? styles40.controlVertical : styles40.control, children: [
4422
- /* @__PURE__ */ jsxs44(View44, { onLayout, pointerEvents: "none", style: [vertical ? styles40.trackVertical : styles40.track, { borderRadius: radius3.full, backgroundColor: theme.surface3 }], children: [
4423
- /* @__PURE__ */ jsx51(View44, { style: [styles40.fill, fill, { borderRadius: radius3.full, overflow: "hidden", backgroundColor: theme.accent }], children: tone3 === "gradient" ? /* @__PURE__ */ jsxs44(Svg23, { width: "100%", height: "100%", "aria-hidden": true, children: [
4424
- /* @__PURE__ */ jsx51(Defs11, { children: /* @__PURE__ */ jsxs44(LinearGradient11, { id: gradientId, x1: "0", y1: vertical ? "1" : "0", x2: vertical ? "0" : "1", y2: "0", children: [
4425
- /* @__PURE__ */ jsx51(Stop11, { offset: "0", stopColor: theme.accent }),
4426
- /* @__PURE__ */ jsx51(Stop11, { offset: "1", stopColor: theme.accent2 })
4798
+ /* @__PURE__ */ jsxs45(View45, { ...responder.panHandlers, style: vertical ? styles41.controlVertical : styles41.control, children: [
4799
+ /* @__PURE__ */ jsxs45(View45, { onLayout, pointerEvents: "none", style: [vertical ? styles41.trackVertical : styles41.track, { borderRadius: radius3.full, backgroundColor: theme.surface3 }], children: [
4800
+ /* @__PURE__ */ jsx52(View45, { style: [styles41.fill, fill, { borderRadius: radius3.full, overflow: "hidden", backgroundColor: theme.accent }], children: tone3 === "gradient" ? /* @__PURE__ */ jsxs45(Svg24, { width: "100%", height: "100%", "aria-hidden": true, children: [
4801
+ /* @__PURE__ */ jsx52(Defs11, { children: /* @__PURE__ */ jsxs45(LinearGradient11, { id: gradientId, x1: "0", y1: vertical ? "1" : "0", x2: vertical ? "0" : "1", y2: "0", children: [
4802
+ /* @__PURE__ */ jsx52(Stop11, { offset: "0", stopColor: theme.accent }),
4803
+ /* @__PURE__ */ jsx52(Stop11, { offset: "1", stopColor: theme.accent2 })
4427
4804
  ] }) }),
4428
- /* @__PURE__ */ jsx51(Rect4, { width: "100%", height: "100%", fill: `url(#${gradientId})` })
4805
+ /* @__PURE__ */ jsx52(Rect4, { width: "100%", height: "100%", fill: `url(#${gradientId})` })
4429
4806
  ] }) : null }),
4430
- tickValues.map((t) => /* @__PURE__ */ jsx51(View44, { style: [vertical ? styles40.tickVertical : styles40.tick, along(pct(t)), { backgroundColor: t > lo && t < hi ? theme.onAccent : theme.borderStrong }] }, t))
4807
+ tickValues.map((t) => /* @__PURE__ */ jsx52(View45, { style: [vertical ? styles41.tickVertical : styles41.tick, along(pct(t)), { backgroundColor: t > lo && t < hi ? theme.onAccent : theme.borderStrong }] }, t))
4431
4808
  ] }),
4432
- current.map((v, i) => /* @__PURE__ */ jsx51(
4433
- View44,
4809
+ current.map((v, i) => /* @__PURE__ */ jsx52(
4810
+ View45,
4434
4811
  {
4435
4812
  accessible: true,
4436
4813
  role: "slider",
@@ -4449,16 +4826,16 @@ function Slider({
4449
4826
  onValueCommit?.(out(values));
4450
4827
  },
4451
4828
  pointerEvents: "none",
4452
- style: [styles40.thumb, vertical ? { bottom: pct(v) * length, left: (44 - THUMB) / 2, marginLeft: 0, marginTop: 0 } : { left: pct(v) * length - THUMB / 2, top: 0 }, { borderColor: theme.accent, backgroundColor: theme.textOnMedia, shadowColor: theme.scrimStrong }],
4453
- children: floatingValue === "always" || floatingValue && dragging === i ? /* @__PURE__ */ jsx51(View44, { "aria-hidden": true, style: [vertical ? styles40.bubbleVertical : styles40.bubble, { backgroundColor: theme.textPrimary, borderRadius: radius3.md }], children: /* @__PURE__ */ jsx51(Text17, { style: [styles40.bubbleText, { color: theme.surface0 }], children: formatValue(v) }) }) : null
4829
+ style: [styles41.thumb, vertical ? { bottom: pct(v) * length, left: (44 - THUMB) / 2, marginLeft: 0, marginTop: 0 } : { left: pct(v) * length - THUMB / 2, top: 0 }, { borderColor: theme.accent, backgroundColor: theme.textOnMedia, shadowColor: theme.scrimStrong }],
4830
+ children: floatingValue === "always" || floatingValue && dragging === i ? /* @__PURE__ */ jsx52(View45, { "aria-hidden": true, style: [vertical ? styles41.bubbleVertical : styles41.bubble, { backgroundColor: theme.textPrimary, borderRadius: radius3.md }], children: /* @__PURE__ */ jsx52(Text17, { style: [styles41.bubbleText, { color: theme.surface0 }], children: formatValue(v) }) }) : null
4454
4831
  },
4455
4832
  i
4456
4833
  ))
4457
4834
  ] }),
4458
- marks2?.length && !vertical ? /* @__PURE__ */ jsx51(View44, { "aria-hidden": true, style: styles40.marks, children: marks2.map((m) => /* @__PURE__ */ jsx51(Text17, { style: [styles40.mark, { left: pct(m.value) * length, color: theme.textSecondary, transform: [{ translateX: m.value === min ? 0 : m.value === max ? -40 : -20 }], textAlign: m.value === min ? "left" : m.value === max ? "right" : "center" }], children: m.label }, m.value)) }) : null
4835
+ marks2?.length && !vertical ? /* @__PURE__ */ jsx52(View45, { "aria-hidden": true, style: styles41.marks, children: marks2.map((m) => /* @__PURE__ */ jsx52(Text17, { style: [styles41.mark, { left: pct(m.value) * length, color: theme.textSecondary, transform: [{ translateX: m.value === min ? 0 : m.value === max ? -40 : -20 }], textAlign: m.value === min ? "left" : m.value === max ? "right" : "center" }], children: m.label }, m.value)) }) : null
4459
4836
  ] });
4460
4837
  }
4461
- var styles40 = StyleSheet40.create({
4838
+ var styles41 = StyleSheet41.create({
4462
4839
  root: { gap: 8, alignSelf: "stretch" },
4463
4840
  rootVertical: { alignSelf: "flex-start", alignItems: "center" },
4464
4841
  header: { flexDirection: "row", justifyContent: "space-between", alignItems: "baseline", gap: 12 },
@@ -4494,10 +4871,10 @@ var styles40 = StyleSheet40.create({
4494
4871
 
4495
4872
  // src/native/spinner.tsx
4496
4873
  import { ActivityIndicator as ActivityIndicator2 } from "react-native";
4497
- import { jsx as jsx52 } from "react/jsx-runtime";
4874
+ import { jsx as jsx53 } from "react/jsx-runtime";
4498
4875
  function Spinner({ label, size = "md", ...props }) {
4499
4876
  const { theme } = useTheme();
4500
- return /* @__PURE__ */ jsx52(
4877
+ return /* @__PURE__ */ jsx53(
4501
4878
  ActivityIndicator2,
4502
4879
  {
4503
4880
  accessible: true,
@@ -4512,17 +4889,17 @@ function Spinner({ label, size = "md", ...props }) {
4512
4889
  }
4513
4890
 
4514
4891
  // src/native/splash-handoff.tsx
4515
- import * as React38 from "react";
4516
- import { Animated as Animated22, Easing as Easing12, StyleSheet as StyleSheet41, View as View45 } from "react-native";
4517
- import { jsx as jsx53 } from "react/jsx-runtime";
4892
+ import * as React39 from "react";
4893
+ import { Animated as Animated23, Easing as Easing13, StyleSheet as StyleSheet42, View as View46 } from "react-native";
4894
+ import { jsx as jsx54 } from "react/jsx-runtime";
4518
4895
  function SplashHandoff({ product, ready, onShown, onDone, size = 96, background, label, duration = 320, style }) {
4519
4896
  const { theme } = useTheme();
4520
4897
  const reduce = useReducedMotion();
4521
- const [opacity] = React38.useState(() => new Animated22.Value(1));
4522
- const [gone, setGone] = React38.useState(false);
4523
- React38.useEffect(() => {
4898
+ const [opacity] = React39.useState(() => new Animated23.Value(1));
4899
+ const [gone, setGone] = React39.useState(false);
4900
+ React39.useEffect(() => {
4524
4901
  if (!ready) return;
4525
- const animation = Animated22.timing(opacity, { toValue: 0, duration: reduce ? 0 : duration, easing: Easing12.out(Easing12.ease), useNativeDriver: true });
4902
+ const animation = Animated23.timing(opacity, { toValue: 0, duration: reduce ? 0 : duration, easing: Easing13.out(Easing13.ease), useNativeDriver: true });
4526
4903
  animation.start(({ finished }) => {
4527
4904
  if (finished) {
4528
4905
  setGone(true);
@@ -4532,8 +4909,8 @@ function SplashHandoff({ product, ready, onShown, onDone, size = 96, background,
4532
4909
  return () => animation.stop();
4533
4910
  }, [ready, reduce, duration, opacity, onDone]);
4534
4911
  if (gone) return null;
4535
- return /* @__PURE__ */ jsx53(
4536
- Animated22.View,
4912
+ return /* @__PURE__ */ jsx54(
4913
+ Animated23.View,
4537
4914
  {
4538
4915
  accessible: true,
4539
4916
  role: "progressbar",
@@ -4541,30 +4918,30 @@ function SplashHandoff({ product, ready, onShown, onDone, size = 96, background,
4541
4918
  "aria-busy": true,
4542
4919
  pointerEvents: ready ? "none" : "auto",
4543
4920
  onLayout: onShown,
4544
- style: [StyleSheet41.absoluteFill, styles41.root, { backgroundColor: background ?? theme.surface0, opacity }, style],
4545
- children: /* @__PURE__ */ jsx53(View45, { children: /* @__PURE__ */ jsx53(ProductMark, { id: product, size, animated: true }) })
4921
+ style: [StyleSheet42.absoluteFill, styles42.root, { backgroundColor: background ?? theme.surface0, opacity }, style],
4922
+ children: /* @__PURE__ */ jsx54(View46, { children: /* @__PURE__ */ jsx54(ProductMark, { id: product, size, animated: true }) })
4546
4923
  }
4547
4924
  );
4548
4925
  }
4549
- var styles41 = StyleSheet41.create({ root: { alignItems: "center", justifyContent: "center", zIndex: 100 } });
4926
+ var styles42 = StyleSheet42.create({ root: { alignItems: "center", justifyContent: "center", zIndex: 100 } });
4550
4927
 
4551
4928
  // src/native/step-progress.tsx
4552
- import { Pressable as Pressable21, StyleSheet as StyleSheet42, View as View46 } from "react-native";
4553
- import Svg24, { Path as Path19 } from "react-native-svg";
4554
- import { jsx as jsx54, jsxs as jsxs45 } from "react/jsx-runtime";
4929
+ import { Pressable as Pressable22, StyleSheet as StyleSheet43, View as View47 } from "react-native";
4930
+ import Svg25, { Path as Path20 } from "react-native-svg";
4931
+ import { jsx as jsx55, jsxs as jsxs46 } from "react/jsx-runtime";
4555
4932
  function StepProgress({ step, total, label, backLabel, onBack, trailing, style }) {
4556
4933
  const { theme, insets } = useTheme();
4557
- const words = label(step, total);
4558
- return /* @__PURE__ */ jsxs45(View46, { style: [styles42.root, { paddingTop: insets.top + 8 }, style], children: [
4559
- /* @__PURE__ */ jsxs45(View46, { style: styles42.row, children: [
4560
- onBack && backLabel ? /* @__PURE__ */ jsx54(Pressable21, { role: "button", "aria-label": backLabel, hitSlop: 10, onPress: onBack, style: styles42.back, children: /* @__PURE__ */ jsx54(Svg24, { width: 22, height: 22, viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx54(Path19, { d: "M15 5l-7 7 7 7", stroke: theme.textPrimary, strokeWidth: 2.4, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) }) }) : /* @__PURE__ */ jsx54(View46, { style: styles42.back }),
4561
- /* @__PURE__ */ jsx54(View46, { accessible: true, role: "progressbar", "aria-label": words, "aria-valuemin": 1, "aria-valuemax": total, "aria-valuenow": step, "aria-valuetext": words, style: styles42.bars, children: Array.from({ length: total }, (_, i) => /* @__PURE__ */ jsx54(View46, { style: [styles42.bar, { backgroundColor: i < step ? theme.accent : theme.surface3 }] }, i)) }),
4562
- /* @__PURE__ */ jsx54(View46, { style: styles42.trailing, children: trailing })
4934
+ const words2 = label(step, total);
4935
+ return /* @__PURE__ */ jsxs46(View47, { style: [styles43.root, { paddingTop: insets.top + 8 }, style], children: [
4936
+ /* @__PURE__ */ jsxs46(View47, { style: styles43.row, children: [
4937
+ onBack && backLabel ? /* @__PURE__ */ jsx55(Pressable22, { role: "button", "aria-label": backLabel, hitSlop: 10, onPress: onBack, style: styles43.back, children: /* @__PURE__ */ jsx55(Svg25, { width: 22, height: 22, viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx55(Path20, { d: "M15 5l-7 7 7 7", stroke: theme.textPrimary, strokeWidth: 2.4, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) }) }) : /* @__PURE__ */ jsx55(View47, { style: styles43.back }),
4938
+ /* @__PURE__ */ jsx55(View47, { accessible: true, role: "progressbar", "aria-label": words2, "aria-valuemin": 1, "aria-valuemax": total, "aria-valuenow": step, "aria-valuetext": words2, style: styles43.bars, children: Array.from({ length: total }, (_, i) => /* @__PURE__ */ jsx55(View47, { style: [styles43.bar, { backgroundColor: i < step ? theme.accent : theme.surface3 }] }, i)) }),
4939
+ /* @__PURE__ */ jsx55(View47, { style: styles43.trailing, children: trailing })
4563
4940
  ] }),
4564
- /* @__PURE__ */ jsx54(Txt, { variant: "caption", tone: "secondary", style: styles42.words, "aria-hidden": true, children: words })
4941
+ /* @__PURE__ */ jsx55(Txt, { variant: "caption", tone: "secondary", style: styles43.words, "aria-hidden": true, children: words2 })
4565
4942
  ] });
4566
4943
  }
4567
- var styles42 = StyleSheet42.create({
4944
+ var styles43 = StyleSheet43.create({
4568
4945
  root: { paddingHorizontal: 12, gap: 6 },
4569
4946
  row: { flexDirection: "row", alignItems: "center", gap: 8 },
4570
4947
  back: { width: 40, height: 40, alignItems: "center", justifyContent: "center" },
@@ -4575,36 +4952,36 @@ var styles42 = StyleSheet42.create({
4575
4952
  });
4576
4953
 
4577
4954
  // src/native/stepper.tsx
4578
- import { StyleSheet as StyleSheet43, View as View47 } from "react-native";
4579
- import Svg25, { Circle as Circle13, Path as Path20 } from "react-native-svg";
4580
- import { jsx as jsx55, jsxs as jsxs46 } from "react/jsx-runtime";
4955
+ import { StyleSheet as StyleSheet44, View as View48 } from "react-native";
4956
+ import Svg26, { Circle as Circle13, Path as Path21 } from "react-native-svg";
4957
+ import { jsx as jsx56, jsxs as jsxs47 } from "react/jsx-runtime";
4581
4958
  var WORDS = { done: "done", current: "in progress", upcoming: "to come", error: "failed" };
4582
4959
  function Stepper({ steps, current = 0, orientation = "vertical", statusLabels, "aria-label": label, style }) {
4583
4960
  const { theme } = useTheme();
4584
- const words = { ...WORDS, ...statusLabels };
4961
+ const words2 = { ...WORDS, ...statusLabels };
4585
4962
  const vertical = orientation === "vertical";
4586
- return /* @__PURE__ */ jsx55(View47, { role: "list", "aria-label": label, style: [vertical ? styles43.column : styles43.row, style], children: steps.map((step, i) => {
4963
+ return /* @__PURE__ */ jsx56(View48, { role: "list", "aria-label": label, style: [vertical ? styles44.column : styles44.row, style], children: steps.map((step, i) => {
4587
4964
  const status = step.status ?? (i < current ? "done" : i === current ? "current" : "upcoming");
4588
4965
  const last = i === steps.length - 1;
4589
- const node = status === "current" ? /* @__PURE__ */ jsx55(LoaderGlyph, { value: step.value ?? null, size: 24 }) : status === "error" ? /* @__PURE__ */ jsx55(LoaderGlyph, { state: "error", size: 24 }) : /* @__PURE__ */ jsxs46(Svg25, { width: 24, height: 24, viewBox: "0 0 24 24", "aria-hidden": true, children: [
4590
- /* @__PURE__ */ jsx55(Circle13, { cx: 12, cy: 12, r: 10, fill: status === "done" ? theme.accent : "none", stroke: status === "done" ? theme.accent : theme.borderStrong, strokeWidth: 2 }),
4591
- status === "done" ? /* @__PURE__ */ jsx55(Path20, { d: "M7.5 12.3l3 3 6-6.3", stroke: theme.onAccent, strokeWidth: 2.2, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) : null
4966
+ const node = status === "current" ? /* @__PURE__ */ jsx56(LoaderGlyph, { value: step.value ?? null, size: 24 }) : status === "error" ? /* @__PURE__ */ jsx56(LoaderGlyph, { state: "error", size: 24 }) : /* @__PURE__ */ jsxs47(Svg26, { width: 24, height: 24, viewBox: "0 0 24 24", "aria-hidden": true, children: [
4967
+ /* @__PURE__ */ jsx56(Circle13, { cx: 12, cy: 12, r: 10, fill: status === "done" ? theme.accent : "none", stroke: status === "done" ? theme.accent : theme.borderStrong, strokeWidth: 2 }),
4968
+ status === "done" ? /* @__PURE__ */ jsx56(Path21, { d: "M7.5 12.3l3 3 6-6.3", stroke: theme.onAccent, strokeWidth: 2.2, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) : null
4592
4969
  ] });
4593
- const connector = !last ? /* @__PURE__ */ jsx55(View47, { "aria-hidden": true, style: [vertical ? styles43.vLine : styles43.hLine, { backgroundColor: status === "done" ? theme.accent : theme.borderDefault }] }) : null;
4594
- return /* @__PURE__ */ jsxs46(View47, { role: "listitem", accessible: true, "aria-label": `${step.title}, ${words[status]}`, style: vertical ? styles43.vStep : styles43.hStep, children: [
4595
- /* @__PURE__ */ jsxs46(View47, { style: vertical ? styles43.vRail : styles43.hRail, children: [
4970
+ const connector = !last ? /* @__PURE__ */ jsx56(View48, { "aria-hidden": true, style: [vertical ? styles44.vLine : styles44.hLine, { backgroundColor: status === "done" ? theme.accent : theme.borderDefault }] }) : null;
4971
+ return /* @__PURE__ */ jsxs47(View48, { role: "listitem", accessible: true, "aria-label": `${step.title}, ${words2[status]}`, style: vertical ? styles44.vStep : styles44.hStep, children: [
4972
+ /* @__PURE__ */ jsxs47(View48, { style: vertical ? styles44.vRail : styles44.hRail, children: [
4596
4973
  node,
4597
4974
  connector
4598
4975
  ] }),
4599
- /* @__PURE__ */ jsxs46(View47, { style: [styles43.body, vertical && !last ? { paddingBottom: 20 } : null], children: [
4600
- /* @__PURE__ */ jsx55(Txt, { variant: "label", tone: status === "upcoming" ? "secondary" : "text", numberOfLines: vertical ? void 0 : 2, children: step.title }),
4601
- step.description ? /* @__PURE__ */ jsx55(Txt, { variant: "caption", tone: "secondary", children: step.description }) : null,
4602
- step.content && (status === "current" || status === "error") ? /* @__PURE__ */ jsx55(View47, { style: styles43.content, children: step.content }) : null
4976
+ /* @__PURE__ */ jsxs47(View48, { style: [styles44.body, vertical && !last ? { paddingBottom: 20 } : null], children: [
4977
+ /* @__PURE__ */ jsx56(Txt, { variant: "label", tone: status === "upcoming" ? "secondary" : "text", numberOfLines: vertical ? void 0 : 2, children: step.title }),
4978
+ step.description ? /* @__PURE__ */ jsx56(Txt, { variant: "caption", tone: "secondary", children: step.description }) : null,
4979
+ step.content && (status === "current" || status === "error") ? /* @__PURE__ */ jsx56(View48, { style: styles44.content, children: step.content }) : null
4603
4980
  ] })
4604
4981
  ] }, i);
4605
4982
  }) });
4606
4983
  }
4607
- var styles43 = StyleSheet43.create({
4984
+ var styles44 = StyleSheet44.create({
4608
4985
  column: { gap: 0 },
4609
4986
  row: { flexDirection: "row" },
4610
4987
  vStep: { flexDirection: "row", gap: 12 },
@@ -4618,59 +4995,59 @@ var styles43 = StyleSheet43.create({
4618
4995
  });
4619
4996
 
4620
4997
  // src/native/swipe-deck.tsx
4621
- import * as React39 from "react";
4622
- import { AccessibilityInfo as AccessibilityInfo14, Animated as Animated23, Image as Image5, PanResponder as PanResponder3, Platform as Platform4, Pressable as Pressable22, StyleSheet as StyleSheet44, useWindowDimensions as useWindowDimensions2, View as View48 } from "react-native";
4623
- import Svg26, { Defs as Defs12, LinearGradient as LinearGradient12, Path as Path21, Rect as Rect5, Stop as Stop12 } from "react-native-svg";
4624
- import { Fragment as Fragment8, jsx as jsx56, jsxs as jsxs47 } from "react/jsx-runtime";
4998
+ import * as React40 from "react";
4999
+ import { AccessibilityInfo as AccessibilityInfo14, Animated as Animated24, Image as Image5, PanResponder as PanResponder3, Platform as Platform4, Pressable as Pressable23, StyleSheet as StyleSheet45, useWindowDimensions as useWindowDimensions2, View as View49 } from "react-native";
5000
+ import Svg27, { Defs as Defs12, LinearGradient as LinearGradient12, Path as Path22, Rect as Rect5, Stop as Stop12 } from "react-native-svg";
5001
+ import { Fragment as Fragment8, jsx as jsx57, jsxs as jsxs48 } from "react/jsx-runtime";
4625
5002
  function PersonCard({ photos, name, age, badge, meta, bio, footer, photoLabel = (n, t) => `Photo ${n} of ${t}`, style }) {
4626
5003
  const { theme, radius: radius3 } = useTheme();
4627
- const [index, setIndex] = React39.useState(0);
5004
+ const [index, setIndex] = React40.useState(0);
4628
5005
  const gradient = useSvgId("kz-profile-");
4629
- const [box, setBox] = React39.useState(null);
5006
+ const [box, setBox] = React40.useState(null);
4630
5007
  const photo = photos[index];
4631
- return /* @__PURE__ */ jsxs47(
4632
- View48,
5008
+ return /* @__PURE__ */ jsxs48(
5009
+ View49,
4633
5010
  {
4634
5011
  accessible: Platform4.OS !== "web",
4635
5012
  accessibilityActions: photos.length > 1 ? [{ name: "increment" }, { name: "decrement" }] : [],
4636
5013
  onAccessibilityAction: (e) => setIndex((i) => Math.max(0, Math.min(photos.length - 1, i + (e.nativeEvent.actionName === "increment" ? 1 : -1)))),
4637
5014
  role: Platform4.OS === "web" ? "group" : "img",
4638
5015
  "aria-label": [`${name}${age !== void 0 ? `, ${age}` : ""}`, bio, photos.length > 1 ? photoLabel(index + 1, photos.length) : null].filter(Boolean).join(". "),
4639
- style: [styles44.card, { borderRadius: radius3.xl, backgroundColor: theme.media }, style],
5016
+ style: [styles45.card, { borderRadius: radius3.xl, backgroundColor: theme.media }, style],
4640
5017
  children: [
4641
- photo ? /* @__PURE__ */ jsx56(Image5, { testID: "person-card-photo", source: { uri: photo.uri }, style: StyleSheet44.absoluteFill, resizeMode: "cover" }) : null,
4642
- photos.length > 1 ? /* @__PURE__ */ jsxs47(Fragment8, { children: [
4643
- /* @__PURE__ */ jsx56(View48, { style: styles44.bars, "aria-hidden": true, children: photos.map((_, i) => /* @__PURE__ */ jsx56(View48, { style: [styles44.bar, { backgroundColor: theme.textOnMedia, opacity: i === index ? 1 : 0.4 }] }, i)) }),
4644
- /* @__PURE__ */ jsx56(Pressable22, { "aria-hidden": true, accessible: false, focusable: false, tabIndex: -1, style: [styles44.half, { left: 0 }], onPress: () => setIndex((i) => Math.max(0, i - 1)) }),
4645
- /* @__PURE__ */ jsx56(Pressable22, { "aria-hidden": true, accessible: false, focusable: false, tabIndex: -1, style: [styles44.half, { right: 0 }], onPress: () => setIndex((i) => Math.min(photos.length - 1, i + 1)) })
5018
+ photo ? /* @__PURE__ */ jsx57(Image5, { testID: "person-card-photo", source: { uri: photo.uri }, style: StyleSheet45.absoluteFill, resizeMode: "cover" }) : null,
5019
+ photos.length > 1 ? /* @__PURE__ */ jsxs48(Fragment8, { children: [
5020
+ /* @__PURE__ */ jsx57(View49, { style: styles45.bars, "aria-hidden": true, children: photos.map((_, i) => /* @__PURE__ */ jsx57(View49, { style: [styles45.bar, { backgroundColor: theme.textOnMedia, opacity: i === index ? 1 : 0.4 }] }, i)) }),
5021
+ /* @__PURE__ */ jsx57(Pressable23, { "aria-hidden": true, accessible: false, focusable: false, tabIndex: -1, style: [styles45.half, { left: 0 }], onPress: () => setIndex((i) => Math.max(0, i - 1)) }),
5022
+ /* @__PURE__ */ jsx57(Pressable23, { "aria-hidden": true, accessible: false, focusable: false, tabIndex: -1, style: [styles45.half, { right: 0 }], onPress: () => setIndex((i) => Math.min(photos.length - 1, i + 1)) })
4646
5023
  ] }) : null,
4647
- /* @__PURE__ */ jsxs47(
4648
- View48,
5024
+ /* @__PURE__ */ jsxs48(
5025
+ View49,
4649
5026
  {
4650
5027
  testID: "person-card-overlay",
4651
5028
  pointerEvents: "box-none",
4652
- style: styles44.bottom,
5029
+ style: styles45.bottom,
4653
5030
  onLayout: (e) => setBox({ width: e.nativeEvent.layout.width, height: e.nativeEvent.layout.height }),
4654
5031
  children: [
4655
- box ? /* @__PURE__ */ jsxs47(Svg26, { testID: "person-card-scrim", style: styles44.scrim, width: box.width, height: box.height, "aria-hidden": true, children: [
4656
- /* @__PURE__ */ jsx56(Defs12, { children: /* @__PURE__ */ jsxs47(LinearGradient12, { id: gradient, x1: "0", y1: "0", x2: "0", y2: "1", children: [
4657
- /* @__PURE__ */ jsx56(Stop12, { offset: "0", stopColor: theme.scrimStrong, stopOpacity: 0 }),
4658
- /* @__PURE__ */ jsx56(Stop12, { offset: "0.5", stopColor: theme.scrimStrong, stopOpacity: 0.8 }),
4659
- /* @__PURE__ */ jsx56(Stop12, { offset: "1", stopColor: theme.scrimStrong, stopOpacity: 1 })
5032
+ box ? /* @__PURE__ */ jsxs48(Svg27, { testID: "person-card-scrim", style: styles45.scrim, width: box.width, height: box.height, "aria-hidden": true, children: [
5033
+ /* @__PURE__ */ jsx57(Defs12, { children: /* @__PURE__ */ jsxs48(LinearGradient12, { id: gradient, x1: "0", y1: "0", x2: "0", y2: "1", children: [
5034
+ /* @__PURE__ */ jsx57(Stop12, { offset: "0", stopColor: theme.scrimStrong, stopOpacity: 0 }),
5035
+ /* @__PURE__ */ jsx57(Stop12, { offset: "0.5", stopColor: theme.scrimStrong, stopOpacity: 0.8 }),
5036
+ /* @__PURE__ */ jsx57(Stop12, { offset: "1", stopColor: theme.scrimStrong, stopOpacity: 1 })
4660
5037
  ] }) }),
4661
- /* @__PURE__ */ jsx56(Rect5, { x: 0, y: 0, width: box.width, height: box.height, fill: `url(#${gradient})` })
5038
+ /* @__PURE__ */ jsx57(Rect5, { x: 0, y: 0, width: box.width, height: box.height, fill: `url(#${gradient})` })
4662
5039
  ] }) : null,
4663
- /* @__PURE__ */ jsxs47(View48, { style: styles44.text, children: [
4664
- /* @__PURE__ */ jsxs47(View48, { style: styles44.nameRow, children: [
4665
- /* @__PURE__ */ jsxs47(Txt, { variant: "display", tone: "onMedia", style: styles44.name, numberOfLines: 1, children: [
5040
+ /* @__PURE__ */ jsxs48(View49, { style: styles45.text, children: [
5041
+ /* @__PURE__ */ jsxs48(View49, { style: styles45.nameRow, children: [
5042
+ /* @__PURE__ */ jsxs48(Txt, { variant: "display", tone: "onMedia", style: styles45.name, numberOfLines: 1, children: [
4666
5043
  name,
4667
- age !== void 0 ? /* @__PURE__ */ jsx56(Txt, { variant: "display", tone: "onMedia", style: styles44.age, children: ` ${age}` }) : null
5044
+ age !== void 0 ? /* @__PURE__ */ jsx57(Txt, { variant: "display", tone: "onMedia", style: styles45.age, children: ` ${age}` }) : null
4668
5045
  ] }),
4669
5046
  badge
4670
5047
  ] }),
4671
5048
  meta,
4672
- bio ? /* @__PURE__ */ jsx56(Txt, { tone: "onMedia", numberOfLines: 2, children: bio }) : null,
4673
- footer ? /* @__PURE__ */ jsx56(View48, { style: styles44.footer, children: footer }) : null
5049
+ bio ? /* @__PURE__ */ jsx57(Txt, { tone: "onMedia", numberOfLines: 2, children: bio }) : null,
5050
+ footer ? /* @__PURE__ */ jsx57(View49, { style: styles45.footer, children: footer }) : null
4674
5051
  ] })
4675
5052
  ]
4676
5053
  }
@@ -4679,13 +5056,13 @@ function PersonCard({ photos, name, age, badge, meta, bio, footer, photoLabel =
4679
5056
  }
4680
5057
  );
4681
5058
  }
4682
- function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty, labels, hideButtons, style }) {
5059
+ function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty: empty2, labels, hideButtons, style }) {
4683
5060
  const { theme, haptic } = useTheme();
4684
5061
  const reduce = useReducedMotion();
4685
5062
  const { width } = useWindowDimensions2();
4686
- const [x] = React39.useState(() => new Animated23.Value(0));
5063
+ const [x] = React40.useState(() => new Animated24.Value(0));
4687
5064
  const top = items2[0];
4688
- const decide = React39.useCallback(
5065
+ const decide = React40.useCallback(
4689
5066
  (direction) => {
4690
5067
  if (!top) return;
4691
5068
  haptic("impact");
@@ -4695,18 +5072,18 @@ function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty, labels, h
4695
5072
  if (items2.length === 1 && labels.empty) AccessibilityInfo14.announceForAccessibility(labels.empty);
4696
5073
  };
4697
5074
  if (reduce) return done();
4698
- Animated23.timing(x, { toValue: (direction === "like" ? 1.4 : -1.4) * width, duration: 220, useNativeDriver: true }).start(done);
5075
+ Animated24.timing(x, { toValue: (direction === "like" ? 1.4 : -1.4) * width, duration: 220, useNativeDriver: true }).start(done);
4699
5076
  },
4700
5077
  [top, haptic, reduce, x, width, onSwipe, items2.length, labels.empty]
4701
5078
  );
4702
- const pan = React39.useMemo(
5079
+ const pan = React40.useMemo(
4703
5080
  () => PanResponder3.create({
4704
5081
  onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 8 && Math.abs(g.dx) > Math.abs(g.dy),
4705
5082
  onPanResponderMove: (_, g) => x.setValue(g.dx),
4706
5083
  onPanResponderRelease: (_, g) => {
4707
5084
  if (g.dx > width / 3 || g.vx > 1) decide("like");
4708
5085
  else if (g.dx < -width / 3 || g.vx < -1) decide("pass");
4709
- else Animated23.spring(x, { toValue: 0, useNativeDriver: true, friction: 6 }).start();
5086
+ else Animated24.spring(x, { toValue: 0, useNativeDriver: true, friction: 6 }).start();
4710
5087
  }
4711
5088
  }),
4712
5089
  [x, width, decide]
@@ -4714,27 +5091,27 @@ function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty, labels, h
4714
5091
  const rotate = x.interpolate({ inputRange: [-width, 0, width], outputRange: ["-14deg", "0deg", "14deg"] });
4715
5092
  const likeOpacity = x.interpolate({ inputRange: [0, width / 4], outputRange: [0, 1], extrapolate: "clamp" });
4716
5093
  const passOpacity = x.interpolate({ inputRange: [-width / 4, 0], outputRange: [1, 0], extrapolate: "clamp" });
4717
- const button = (direction) => /* @__PURE__ */ jsx56(
4718
- Pressable22,
5094
+ const button = (direction) => /* @__PURE__ */ jsx57(
5095
+ Pressable23,
4719
5096
  {
4720
5097
  role: "button",
4721
5098
  "aria-label": direction === "like" ? labels.like : labels.pass,
4722
5099
  disabled: !top,
4723
5100
  onPress: () => decide(direction),
4724
5101
  style: ({ pressed }) => [
4725
- styles44.button,
5102
+ styles45.button,
4726
5103
  { borderColor: direction === "like" ? theme.success : theme.danger, backgroundColor: theme.surface1, transform: [{ scale: pressed ? 0.92 : 1 }], opacity: top ? 1 : 0.4 }
4727
5104
  ],
4728
- children: /* @__PURE__ */ jsx56(Svg26, { width: 28, height: 28, viewBox: "0 0 24 24", "aria-hidden": true, children: direction === "like" ? /* @__PURE__ */ jsx56(Path21, { d: "M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z", fill: theme.success }) : /* @__PURE__ */ jsx56(Path21, { d: "M6 6l12 12M18 6 6 18", stroke: theme.danger, strokeWidth: 3, strokeLinecap: "round" }) })
5105
+ children: /* @__PURE__ */ jsx57(Svg27, { width: 28, height: 28, viewBox: "0 0 24 24", "aria-hidden": true, children: direction === "like" ? /* @__PURE__ */ jsx57(Path22, { d: "M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z", fill: theme.success }) : /* @__PURE__ */ jsx57(Path22, { d: "M6 6l12 12M18 6 6 18", stroke: theme.danger, strokeWidth: 3, strokeLinecap: "round" }) })
4729
5106
  }
4730
5107
  );
4731
- return /* @__PURE__ */ jsxs47(View48, { style: [styles44.deck, style], children: [
4732
- /* @__PURE__ */ jsxs47(View48, { style: styles44.stack, children: [
4733
- !top ? empty ?? null : null,
5108
+ return /* @__PURE__ */ jsxs48(View49, { style: [styles45.deck, style], children: [
5109
+ /* @__PURE__ */ jsxs48(View49, { style: styles45.stack, children: [
5110
+ !top ? empty2 ?? null : null,
4734
5111
  items2.slice(0, 2).reverse().map((item) => {
4735
5112
  const isTop = item === top;
4736
- return /* @__PURE__ */ jsxs47(
4737
- Animated23.View,
5113
+ return /* @__PURE__ */ jsxs48(
5114
+ Animated24.View,
4738
5115
  {
4739
5116
  ...isTop ? pan.panHandlers : {},
4740
5117
  accessibilityActions: isTop ? [{ name: "like", label: labels.like }, { name: "pass", label: labels.pass }] : [],
@@ -4742,12 +5119,12 @@ function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty, labels, h
4742
5119
  "aria-hidden": !isTop,
4743
5120
  importantForAccessibility: isTop ? "auto" : "no-hide-descendants",
4744
5121
  pointerEvents: isTop ? "auto" : "none",
4745
- style: [StyleSheet44.absoluteFill, isTop ? { transform: [{ translateX: x }, { rotate }] } : { transform: [{ scale: 0.96 }], opacity: 0.9 }],
5122
+ style: [StyleSheet45.absoluteFill, isTop ? { transform: [{ translateX: x }, { rotate }] } : { transform: [{ scale: 0.96 }], opacity: 0.9 }],
4746
5123
  children: [
4747
5124
  renderCard(item),
4748
- isTop ? /* @__PURE__ */ jsxs47(Fragment8, { children: [
4749
- /* @__PURE__ */ jsx56(Animated23.View, { pointerEvents: "none", style: [styles44.stamp, styles44.stampLike, { borderColor: theme.success, opacity: likeOpacity }], "aria-hidden": true, children: /* @__PURE__ */ jsx56(Txt, { variant: "title", style: { color: theme.success }, children: labels.likeStamp ?? labels.like.toUpperCase() }) }),
4750
- /* @__PURE__ */ jsx56(Animated23.View, { pointerEvents: "none", style: [styles44.stamp, styles44.stampPass, { borderColor: theme.danger, opacity: passOpacity }], "aria-hidden": true, children: /* @__PURE__ */ jsx56(Txt, { variant: "title", style: { color: theme.danger }, children: labels.passStamp ?? labels.pass.toUpperCase() }) })
5125
+ isTop ? /* @__PURE__ */ jsxs48(Fragment8, { children: [
5126
+ /* @__PURE__ */ jsx57(Animated24.View, { pointerEvents: "none", style: [styles45.stamp, styles45.stampLike, { borderColor: theme.success, opacity: likeOpacity }], "aria-hidden": true, children: /* @__PURE__ */ jsx57(Txt, { variant: "title", style: { color: theme.success }, children: labels.likeStamp ?? labels.like.toUpperCase() }) }),
5127
+ /* @__PURE__ */ jsx57(Animated24.View, { pointerEvents: "none", style: [styles45.stamp, styles45.stampPass, { borderColor: theme.danger, opacity: passOpacity }], "aria-hidden": true, children: /* @__PURE__ */ jsx57(Txt, { variant: "title", style: { color: theme.danger }, children: labels.passStamp ?? labels.pass.toUpperCase() }) })
4751
5128
  ] }) : null
4752
5129
  ]
4753
5130
  },
@@ -4755,13 +5132,13 @@ function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty, labels, h
4755
5132
  );
4756
5133
  })
4757
5134
  ] }),
4758
- hideButtons ? null : /* @__PURE__ */ jsxs47(View48, { style: styles44.buttons, children: [
5135
+ hideButtons ? null : /* @__PURE__ */ jsxs48(View49, { style: styles45.buttons, children: [
4759
5136
  button("pass"),
4760
5137
  button("like")
4761
5138
  ] })
4762
5139
  ] });
4763
5140
  }
4764
- var styles44 = StyleSheet44.create({
5141
+ var styles45 = StyleSheet45.create({
4765
5142
  card: { flex: 1, overflow: "hidden" },
4766
5143
  bars: { position: "absolute", top: 8, left: 8, right: 8, flexDirection: "row", gap: 4 },
4767
5144
  bar: { flex: 1, height: 3, borderRadius: 2 },
@@ -4783,28 +5160,28 @@ var styles44 = StyleSheet44.create({
4783
5160
  });
4784
5161
 
4785
5162
  // src/native/swipeable-row.tsx
4786
- import * as React40 from "react";
4787
- import { Animated as Animated24, PanResponder as PanResponder4, Pressable as Pressable23, StyleSheet as StyleSheet45, View as View49 } from "react-native";
4788
- import { jsx as jsx57, jsxs as jsxs48 } from "react/jsx-runtime";
5163
+ import * as React41 from "react";
5164
+ import { Animated as Animated25, PanResponder as PanResponder4, Pressable as Pressable24, StyleSheet as StyleSheet46, View as View50 } from "react-native";
5165
+ import { jsx as jsx58, jsxs as jsxs49 } from "react/jsx-runtime";
4789
5166
  var toneColor = (t, tone3) => ({ neutral: t.surface3, accent: t.accent, success: t.success, warning: t.warning, danger: t.danger })[tone3 ?? "neutral"];
4790
5167
  var toneText = (tone3) => tone3 === "neutral" || tone3 === void 0 ? "text" : "onAccent";
4791
5168
  function SwipeableRow({ children, trailing = [], leading = [], fullSwipe = 0.6, actionWidth = 80, onActivate, testID, style }) {
4792
5169
  const { theme, haptic } = useTheme();
4793
5170
  const reduce = useReducedMotion();
4794
- const [x] = React40.useState(() => new Animated24.Value(0));
4795
- const [width, setWidth] = React40.useState(0);
4796
- const rest = React40.useRef(0);
4797
- const armed = React40.useRef(false);
5171
+ const [x] = React41.useState(() => new Animated25.Value(0));
5172
+ const [width, setWidth] = React41.useState(0);
5173
+ const rest = React41.useRef(0);
5174
+ const armed = React41.useRef(false);
4798
5175
  const settle = (to) => {
4799
5176
  rest.current = to;
4800
5177
  if (reduce) x.setValue(to);
4801
- else Animated24.spring(x, { toValue: to, useNativeDriver: true, damping: 22, stiffness: 240 }).start();
5178
+ else Animated25.spring(x, { toValue: to, useNativeDriver: true, damping: 22, stiffness: 240 }).start();
4802
5179
  };
4803
5180
  const run = (action) => {
4804
5181
  settle(0);
4805
5182
  action.onPress();
4806
5183
  };
4807
- const pan = React40.useMemo(
5184
+ const pan = React41.useMemo(
4808
5185
  () => PanResponder4.create({
4809
5186
  onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 8 && Math.abs(g.dx) > Math.abs(g.dy) * 1.5,
4810
5187
  onPanResponderMove: (_, g) => {
@@ -4833,19 +5210,19 @@ function SwipeableRow({ children, trailing = [], leading = [], fullSwipe = 0.6,
4833
5210
  [trailing, leading, fullSwipe, width, actionWidth]
4834
5211
  // eslint-disable-line react-hooks/exhaustive-deps -- run/settle are stable in effect
4835
5212
  );
4836
- const side = (actions, edge) => /* @__PURE__ */ jsx57(View49, { "aria-hidden": true, style: [styles45.side, edge === "left" ? { left: 0 } : { right: 0, flexDirection: "row-reverse" }], children: actions.map((action, i) => (
5213
+ const side = (actions, edge) => /* @__PURE__ */ jsx58(View50, { "aria-hidden": true, style: [styles46.side, edge === "left" ? { left: 0 } : { right: 0, flexDirection: "row-reverse" }], children: actions.map((action, i) => (
4837
5214
  // eslint-disable-next-line react-hooks/refs -- runs on a press, never during render
4838
- /* @__PURE__ */ jsxs48(Pressable23, { focusable: false, tabIndex: -1, onPress: () => run(action), style: [styles45.action, { width: actionWidth, backgroundColor: toneColor(theme, action.tone) }], children: [
5215
+ /* @__PURE__ */ jsxs49(Pressable24, { focusable: false, tabIndex: -1, onPress: () => run(action), style: [styles46.action, { width: actionWidth, backgroundColor: toneColor(theme, action.tone) }], children: [
4839
5216
  action.icon,
4840
- /* @__PURE__ */ jsx57(Txt, { variant: "caption", tone: toneText(action.tone), style: styles45.actionText, numberOfLines: 1, children: action.label })
5217
+ /* @__PURE__ */ jsx58(Txt, { variant: "caption", tone: toneText(action.tone), style: styles46.actionText, numberOfLines: 1, children: action.label })
4841
5218
  ] }, i)
4842
5219
  )) });
4843
5220
  const all = [...leading, ...trailing];
4844
- return /* @__PURE__ */ jsxs48(View49, { style: [styles45.root, style], onLayout: (e) => setWidth(e.nativeEvent.layout.width), children: [
5221
+ return /* @__PURE__ */ jsxs49(View50, { style: [styles46.root, style], onLayout: (e) => setWidth(e.nativeEvent.layout.width), children: [
4845
5222
  leading.length > 0 ? side(leading, "left") : null,
4846
5223
  trailing.length > 0 ? side(trailing, "right") : null,
4847
- /* @__PURE__ */ jsx57(
4848
- Animated24.View,
5224
+ /* @__PURE__ */ jsx58(
5225
+ Animated25.View,
4849
5226
  {
4850
5227
  ...pan.panHandlers,
4851
5228
  accessible: true,
@@ -4856,13 +5233,13 @@ function SwipeableRow({ children, trailing = [], leading = [], fullSwipe = 0.6,
4856
5233
  const action = all.find((a) => a.label === e.nativeEvent.actionName);
4857
5234
  if (action) action.onPress();
4858
5235
  },
4859
- style: [styles45.front, { backgroundColor: theme.surface0, transform: [{ translateX: x }] }],
5236
+ style: [styles46.front, { backgroundColor: theme.surface0, transform: [{ translateX: x }] }],
4860
5237
  children
4861
5238
  }
4862
5239
  )
4863
5240
  ] });
4864
5241
  }
4865
- var styles45 = StyleSheet45.create({
5242
+ var styles46 = StyleSheet46.create({
4866
5243
  root: { overflow: "hidden" },
4867
5244
  side: { position: "absolute", top: 0, bottom: 0, flexDirection: "row" },
4868
5245
  action: { alignItems: "center", justifyContent: "center", gap: 4, paddingHorizontal: 6 },
@@ -4871,30 +5248,30 @@ var styles45 = StyleSheet45.create({
4871
5248
  });
4872
5249
 
4873
5250
  // src/native/switch.tsx
4874
- import * as React41 from "react";
4875
- import { Animated as Animated25, Pressable as Pressable24, StyleSheet as StyleSheet46, Text as Text18, View as View50 } from "react-native";
4876
- import { jsx as jsx58, jsxs as jsxs49 } from "react/jsx-runtime";
5251
+ import * as React42 from "react";
5252
+ import { Animated as Animated26, Pressable as Pressable25, StyleSheet as StyleSheet47, Text as Text18, View as View51 } from "react-native";
5253
+ import { jsx as jsx59, jsxs as jsxs50 } from "react/jsx-runtime";
4877
5254
  var SIZES = { sm: { w: 40, h: 24, knob: 18 }, md: { w: 52, h: 32, knob: 26 } };
4878
5255
  function Switch({ label, checked, defaultChecked = false, onCheckedChange, description, showLabel, size = "md", error, disabled, style }) {
4879
5256
  const { theme, motion: motion3, haptic } = useTheme();
4880
- const [own, setOwn] = React41.useState(defaultChecked);
5257
+ const [own, setOwn] = React42.useState(defaultChecked);
4881
5258
  const on = checked ?? own;
4882
5259
  const d = SIZES[size];
4883
5260
  const travel = d.w - d.knob - (d.h - d.knob);
4884
- const [x] = React41.useState(() => new Animated25.Value(on ? 1 : 0));
4885
- React41.useEffect(() => {
4886
- Animated25.timing(x, { toValue: on ? 1 : 0, duration: motion3.duration.base, useNativeDriver: true }).start();
5261
+ const [x] = React42.useState(() => new Animated26.Value(on ? 1 : 0));
5262
+ React42.useEffect(() => {
5263
+ Animated26.timing(x, { toValue: on ? 1 : 0, duration: motion3.duration.base, useNativeDriver: true }).start();
4887
5264
  }, [on, x, motion3.duration.base]);
4888
5265
  const toggle = () => {
4889
5266
  haptic("selection");
4890
5267
  if (checked === void 0) setOwn(!on);
4891
5268
  onCheckedChange?.(!on);
4892
5269
  };
4893
- const track = /* @__PURE__ */ jsx58(View50, { style: [styles46.track, { width: d.w, height: d.h, borderRadius: d.h / 2, backgroundColor: on ? theme.accent : theme.surface3, borderColor: error ? theme.danger : on ? theme.accent : theme.borderDefault }], children: /* @__PURE__ */ jsx58(
4894
- Animated25.View,
5270
+ const track = /* @__PURE__ */ jsx59(View51, { style: [styles47.track, { width: d.w, height: d.h, borderRadius: d.h / 2, backgroundColor: on ? theme.accent : theme.surface3, borderColor: error ? theme.danger : on ? theme.accent : theme.borderDefault }], children: /* @__PURE__ */ jsx59(
5271
+ Animated26.View,
4895
5272
  {
4896
5273
  style: [
4897
- styles46.knob,
5274
+ styles47.knob,
4898
5275
  {
4899
5276
  width: d.knob,
4900
5277
  height: d.knob,
@@ -4916,19 +5293,19 @@ function Switch({ label, checked, defaultChecked = false, onCheckedChange, descr
4916
5293
  onPress: toggle
4917
5294
  };
4918
5295
  if (!showLabel)
4919
- return /* @__PURE__ */ jsx58(Pressable24, { ...a11y, hitSlop: { top: (44 - d.h) / 2, bottom: (44 - d.h) / 2, left: Math.max(0, (44 - d.w) / 2), right: Math.max(0, (44 - d.w) / 2) }, style: [disabled ? styles46.disabled : null, style], children: track });
4920
- return /* @__PURE__ */ jsxs49(View50, { style: [styles46.root, style], children: [
4921
- /* @__PURE__ */ jsxs49(Pressable24, { ...a11y, style: [styles46.row, disabled ? styles46.disabled : null], children: [
4922
- /* @__PURE__ */ jsxs49(View50, { style: styles46.text, children: [
4923
- /* @__PURE__ */ jsx58(Text18, { style: [styles46.label, { color: theme.textPrimary }], children: label }),
4924
- description ? /* @__PURE__ */ jsx58(Text18, { style: [styles46.description, { color: theme.textSecondary }], children: description }) : null
5296
+ return /* @__PURE__ */ jsx59(Pressable25, { ...a11y, hitSlop: { top: (44 - d.h) / 2, bottom: (44 - d.h) / 2, left: Math.max(0, (44 - d.w) / 2), right: Math.max(0, (44 - d.w) / 2) }, style: [disabled ? styles47.disabled : null, style], children: track });
5297
+ return /* @__PURE__ */ jsxs50(View51, { style: [styles47.root, style], children: [
5298
+ /* @__PURE__ */ jsxs50(Pressable25, { ...a11y, style: [styles47.row, disabled ? styles47.disabled : null], children: [
5299
+ /* @__PURE__ */ jsxs50(View51, { style: styles47.text, children: [
5300
+ /* @__PURE__ */ jsx59(Text18, { style: [styles47.label, { color: theme.textPrimary }], children: label }),
5301
+ description ? /* @__PURE__ */ jsx59(Text18, { style: [styles47.description, { color: theme.textSecondary }], children: description }) : null
4925
5302
  ] }),
4926
5303
  track
4927
5304
  ] }),
4928
- error ? /* @__PURE__ */ jsx58(Text18, { role: "alert", "aria-live": "polite", style: [styles46.description, { color: theme.dangerText }], children: error }) : null
5305
+ error ? /* @__PURE__ */ jsx59(Text18, { role: "alert", "aria-live": "polite", style: [styles47.description, { color: theme.dangerText }], children: error }) : null
4929
5306
  ] });
4930
5307
  }
4931
- var styles46 = StyleSheet46.create({
5308
+ var styles47 = StyleSheet47.create({
4932
5309
  root: { gap: 2, alignSelf: "stretch" },
4933
5310
  row: { flexDirection: "row", alignItems: "center", gap: 16, minHeight: 48 },
4934
5311
  text: { flex: 1, gap: 2 },
@@ -4940,16 +5317,16 @@ var styles46 = StyleSheet46.create({
4940
5317
  });
4941
5318
 
4942
5319
  // src/native/tab-bar.tsx
4943
- import { Pressable as Pressable25, StyleSheet as StyleSheet47, Text as Text19, View as View51 } from "react-native";
4944
- import { jsx as jsx59, jsxs as jsxs50 } from "react/jsx-runtime";
5320
+ import { Pressable as Pressable26, StyleSheet as StyleSheet48, Text as Text19, View as View52 } from "react-native";
5321
+ import { jsx as jsx60, jsxs as jsxs51 } from "react/jsx-runtime";
4945
5322
  function TabBar({ items: items2, value, onValueChange, onReselect, "aria-label": label, style }) {
4946
5323
  const { theme, insets, haptic } = useTheme();
4947
- return /* @__PURE__ */ jsx59(View51, { role: "tablist", "aria-label": label, style: [styles47.bar, { backgroundColor: theme.glassBg, borderTopColor: theme.glassBorder, paddingBottom: Math.max(6, insets.bottom) }, style], children: items2.map((item) => {
5324
+ return /* @__PURE__ */ jsx60(View52, { role: "tablist", "aria-label": label, style: [styles48.bar, { backgroundColor: theme.glassBg, borderTopColor: theme.glassBorder, paddingBottom: Math.max(6, insets.bottom) }, style], children: items2.map((item) => {
4948
5325
  const selected = item.value === value;
4949
5326
  const color = selected ? theme.accentText : theme.textSecondary;
4950
5327
  const badge = item.badge === true ? "" : typeof item.badge === "number" && item.badge > 0 ? item.badge > 99 ? "99+" : String(item.badge) : null;
4951
- return /* @__PURE__ */ jsxs50(
4952
- Pressable25,
5328
+ return /* @__PURE__ */ jsxs51(
5329
+ Pressable26,
4953
5330
  {
4954
5331
  role: "tab",
4955
5332
  "aria-selected": selected,
@@ -4958,22 +5335,22 @@ function TabBar({ items: items2, value, onValueChange, onReselect, "aria-label":
4958
5335
  if (selected) onReselect?.(item.value);
4959
5336
  else onValueChange(item.value);
4960
5337
  },
4961
- style: ({ pressed }) => [styles47.item, { opacity: pressed ? 0.7 : 1 }],
5338
+ style: ({ pressed }) => [styles48.item, { opacity: pressed ? 0.7 : 1 }],
4962
5339
  children: [
4963
- /* @__PURE__ */ jsxs50(View51, { "aria-hidden": true, style: styles47.icon, children: [
5340
+ /* @__PURE__ */ jsxs51(View52, { "aria-hidden": true, style: styles48.icon, children: [
4964
5341
  item.icon(selected, color),
4965
- badge !== null ? /* @__PURE__ */ jsx59(View51, { style: [badge ? styles47.count : styles47.dot, { backgroundColor: theme.danger, borderColor: theme.surface1 }], children: badge ? /* @__PURE__ */ jsx59(Text19, { style: [styles47.countText, { color: theme.onAccent }], children: badge }) : null }) : null
5342
+ badge !== null ? /* @__PURE__ */ jsx60(View52, { style: [badge ? styles48.count : styles48.dot, { backgroundColor: theme.danger, borderColor: theme.surface1 }], children: badge ? /* @__PURE__ */ jsx60(Text19, { style: [styles48.countText, { color: theme.onAccent }], children: badge }) : null }) : null
4966
5343
  ] }),
4967
- /* @__PURE__ */ jsx59(Text19, { numberOfLines: 1, style: [styles47.label, { color, fontWeight: selected ? "700" : "500" }], children: item.label }),
4968
- badge !== null && item.badgeLabel ? /* @__PURE__ */ jsx59(Text19, { style: styles47.unseen, children: `, ${item.badgeLabel}` }) : null
5344
+ /* @__PURE__ */ jsx60(Text19, { numberOfLines: 1, style: [styles48.label, { color, fontWeight: selected ? "700" : "500" }], children: item.label }),
5345
+ badge !== null && item.badgeLabel ? /* @__PURE__ */ jsx60(Text19, { style: styles48.unseen, children: `, ${item.badgeLabel}` }) : null
4969
5346
  ]
4970
5347
  },
4971
5348
  item.value
4972
5349
  );
4973
5350
  }) });
4974
5351
  }
4975
- var styles47 = StyleSheet47.create({
4976
- bar: { flexDirection: "row", borderTopWidth: StyleSheet47.hairlineWidth, paddingTop: 6 },
5352
+ var styles48 = StyleSheet48.create({
5353
+ bar: { flexDirection: "row", borderTopWidth: StyleSheet48.hairlineWidth, paddingTop: 6 },
4977
5354
  item: { flex: 1, alignItems: "center", gap: 2, minHeight: 48, justifyContent: "center" },
4978
5355
  icon: { width: 28, height: 26, alignItems: "center", justifyContent: "center" },
4979
5356
  label: { fontSize: 11, lineHeight: 14 },
@@ -4984,12 +5361,12 @@ var styles47 = StyleSheet47.create({
4984
5361
  });
4985
5362
 
4986
5363
  // src/native/tabs.tsx
4987
- import * as React42 from "react";
4988
- import { Pressable as Pressable26, ScrollView as ScrollView7, StyleSheet as StyleSheet48, View as View52 } from "react-native";
4989
- import { jsx as jsx60, jsxs as jsxs51 } from "react/jsx-runtime";
5364
+ import * as React43 from "react";
5365
+ import { Pressable as Pressable27, ScrollView as ScrollView7, StyleSheet as StyleSheet49, View as View53 } from "react-native";
5366
+ import { jsx as jsx61, jsxs as jsxs52 } from "react/jsx-runtime";
4990
5367
  function Tabs({ items: items2, value, defaultValue, onValueChange, "aria-label": label, variant = "underline", style }) {
4991
5368
  const { theme, radius: radius3, haptic } = useTheme();
4992
- const [own, setOwn] = React42.useState(defaultValue ?? items2[0]?.value);
5369
+ const [own, setOwn] = React43.useState(defaultValue ?? items2[0]?.value);
4993
5370
  const current = value ?? own;
4994
5371
  const select = (next) => {
4995
5372
  if (next === current) return;
@@ -5000,8 +5377,8 @@ function Tabs({ items: items2, value, defaultValue, onValueChange, "aria-label":
5000
5377
  const segmented = variant === "segmented";
5001
5378
  const tabs = items2.map((item) => {
5002
5379
  const selected = item.value === current;
5003
- return /* @__PURE__ */ jsx60(
5004
- Pressable26,
5380
+ return /* @__PURE__ */ jsx61(
5381
+ Pressable27,
5005
5382
  {
5006
5383
  role: "tab",
5007
5384
  "aria-selected": selected,
@@ -5009,45 +5386,45 @@ function Tabs({ items: items2, value, defaultValue, onValueChange, "aria-label":
5009
5386
  disabled: item.disabled,
5010
5387
  onPress: () => select(item.value),
5011
5388
  style: [
5012
- segmented ? styles48.segment : styles48.tab,
5389
+ segmented ? styles49.segment : styles49.tab,
5013
5390
  segmented && selected ? { backgroundColor: theme.surface0, borderColor: theme.borderDefault, borderRadius: radius3.sm } : null,
5014
5391
  !segmented ? { borderBottomColor: selected ? theme.accent : "transparent" } : null,
5015
- item.disabled ? styles48.disabled : null
5392
+ item.disabled ? styles49.disabled : null
5016
5393
  ],
5017
- children: /* @__PURE__ */ jsxs51(Txt, { variant: "label", tone: selected ? "text" : "secondary", numberOfLines: 1, children: [
5394
+ children: /* @__PURE__ */ jsxs52(Txt, { variant: "label", tone: selected ? "text" : "secondary", numberOfLines: 1, children: [
5018
5395
  item.label,
5019
- item.count !== void 0 ? /* @__PURE__ */ jsx60(Txt, { variant: "caption", tone: "secondary", children: ` ${item.count}` }) : null
5396
+ item.count !== void 0 ? /* @__PURE__ */ jsx61(Txt, { variant: "caption", tone: "secondary", children: ` ${item.count}` }) : null
5020
5397
  ] })
5021
5398
  },
5022
5399
  item.value
5023
5400
  );
5024
5401
  });
5025
5402
  const panel = items2.find((i) => i.value === current)?.content;
5026
- return /* @__PURE__ */ jsxs51(View52, { style: [styles48.root, style], children: [
5027
- segmented ? /* @__PURE__ */ jsx60(View52, { role: "tablist", "aria-label": label, style: [styles48.track, { backgroundColor: theme.surface2, borderColor: theme.borderSubtle, borderRadius: radius3.md }], children: tabs }) : /* @__PURE__ */ jsx60(View52, { style: [styles48.underline, { borderBottomColor: theme.borderSubtle }], children: /* @__PURE__ */ jsx60(ScrollView7, { horizontal: true, showsHorizontalScrollIndicator: false, role: "tablist", "aria-label": label, contentContainerStyle: styles48.scroll, children: tabs }) }),
5028
- panel !== void 0 ? /* @__PURE__ */ jsx60(View52, { role: "tabpanel", children: panel }) : null
5403
+ return /* @__PURE__ */ jsxs52(View53, { style: [styles49.root, style], children: [
5404
+ segmented ? /* @__PURE__ */ jsx61(View53, { role: "tablist", "aria-label": label, style: [styles49.track, { backgroundColor: theme.surface2, borderColor: theme.borderSubtle, borderRadius: radius3.md }], children: tabs }) : /* @__PURE__ */ jsx61(View53, { style: [styles49.underline, { borderBottomColor: theme.borderSubtle }], children: /* @__PURE__ */ jsx61(ScrollView7, { horizontal: true, showsHorizontalScrollIndicator: false, role: "tablist", "aria-label": label, contentContainerStyle: styles49.scroll, children: tabs }) }),
5405
+ panel !== void 0 ? /* @__PURE__ */ jsx61(View53, { role: "tabpanel", children: panel }) : null
5029
5406
  ] });
5030
5407
  }
5031
- var styles48 = StyleSheet48.create({
5408
+ var styles49 = StyleSheet49.create({
5032
5409
  root: { gap: 12 },
5033
- underline: { borderBottomWidth: StyleSheet48.hairlineWidth },
5410
+ underline: { borderBottomWidth: StyleSheet49.hairlineWidth },
5034
5411
  scroll: { gap: 4, paddingHorizontal: 4 },
5035
5412
  tab: { minHeight: 44, justifyContent: "center", paddingHorizontal: 12, borderBottomWidth: 2 },
5036
- track: { flexDirection: "row", padding: 3, gap: 3, borderWidth: StyleSheet48.hairlineWidth, height: 40 },
5037
- segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth: StyleSheet48.hairlineWidth, borderColor: "transparent" },
5413
+ track: { flexDirection: "row", padding: 3, gap: 3, borderWidth: StyleSheet49.hairlineWidth, height: 40 },
5414
+ segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth: StyleSheet49.hairlineWidth, borderColor: "transparent" },
5038
5415
  disabled: { opacity: 0.4 }
5039
5416
  });
5040
5417
 
5041
5418
  // src/native/tag-selector.tsx
5042
- import { StyleSheet as StyleSheet49, View as View53 } from "react-native";
5043
- import { jsx as jsx61, jsxs as jsxs52 } from "react/jsx-runtime";
5419
+ import { StyleSheet as StyleSheet50, View as View54 } from "react-native";
5420
+ import { jsx as jsx62, jsxs as jsxs53 } from "react/jsx-runtime";
5044
5421
  function TagSelector({ label, options, value, onValueChange, max, countLabel, style }) {
5045
5422
  const { haptic } = useTheme();
5046
5423
  const full = max !== void 0 && value.length >= max;
5047
- return /* @__PURE__ */ jsxs52(View53, { style: [styles49.root, style], children: [
5048
- /* @__PURE__ */ jsx61(View53, { role: "group", "aria-label": label, style: styles49.wrap, children: options.map((option) => {
5424
+ return /* @__PURE__ */ jsxs53(View54, { style: [styles50.root, style], children: [
5425
+ /* @__PURE__ */ jsx62(View54, { role: "group", "aria-label": label, style: styles50.wrap, children: options.map((option) => {
5049
5426
  const on = value.includes(option.value);
5050
- return /* @__PURE__ */ jsx61(
5427
+ return /* @__PURE__ */ jsx62(
5051
5428
  Chip,
5052
5429
  {
5053
5430
  selected: on,
@@ -5061,15 +5438,15 @@ function TagSelector({ label, options, value, onValueChange, max, countLabel, st
5061
5438
  option.value
5062
5439
  );
5063
5440
  }) }),
5064
- max !== void 0 && countLabel ? /* @__PURE__ */ jsx61(Txt, { variant: "caption", tone: full ? "accent" : "secondary", "aria-live": "polite", children: countLabel(value.length, max) }) : null
5441
+ max !== void 0 && countLabel ? /* @__PURE__ */ jsx62(Txt, { variant: "caption", tone: full ? "accent" : "secondary", "aria-live": "polite", children: countLabel(value.length, max) }) : null
5065
5442
  ] });
5066
5443
  }
5067
- var styles49 = StyleSheet49.create({ root: { gap: 8 }, wrap: { flexDirection: "row", flexWrap: "wrap", gap: 8 } });
5444
+ var styles50 = StyleSheet50.create({ root: { gap: 8 }, wrap: { flexDirection: "row", flexWrap: "wrap", gap: 8 } });
5068
5445
 
5069
5446
  // src/native/toast.tsx
5070
- import * as React43 from "react";
5071
- import { AccessibilityInfo as AccessibilityInfo15, Animated as Animated26, PanResponder as PanResponder5, Pressable as Pressable27, StyleSheet as StyleSheet50, Text as Text20, View as View54 } from "react-native";
5072
- import { Fragment as Fragment9, jsx as jsx62, jsxs as jsxs53 } from "react/jsx-runtime";
5447
+ import * as React44 from "react";
5448
+ import { AccessibilityInfo as AccessibilityInfo15, Animated as Animated27, PanResponder as PanResponder5, Pressable as Pressable28, StyleSheet as StyleSheet51, Text as Text20, View as View55 } from "react-native";
5449
+ import { Fragment as Fragment9, jsx as jsx63, jsxs as jsxs54 } from "react/jsx-runtime";
5073
5450
  var items = [];
5074
5451
  var listeners2 = /* @__PURE__ */ new Set();
5075
5452
  var counter = 0;
@@ -5104,93 +5481,93 @@ var toast = Object.assign(show, {
5104
5481
  function ToastView({ item, closeLabel, duration }) {
5105
5482
  const { theme, radius: radius3, haptic } = useTheme();
5106
5483
  const reduce = useReducedMotion();
5107
- const [swipe] = React43.useState(() => new Animated26.Value(0));
5108
- const drag = React43.useMemo(
5484
+ const [swipe] = React44.useState(() => new Animated27.Value(0));
5485
+ const drag = React44.useMemo(
5109
5486
  () => PanResponder5.create({
5110
5487
  onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 8 && Math.abs(g.dx) > Math.abs(g.dy),
5111
5488
  onPanResponderMove: (_, g) => swipe.setValue(g.dx),
5112
5489
  onPanResponderRelease: (_, g) => {
5113
5490
  if (Math.abs(g.dx) > 96 || Math.abs(g.vx) > 0.9) {
5114
- Animated26.timing(swipe, { toValue: Math.sign(g.dx) * 480, duration: 160, useNativeDriver: true }).start(() => dismiss(item.id));
5115
- } else Animated26.spring(swipe, { toValue: 0, useNativeDriver: true }).start();
5491
+ Animated27.timing(swipe, { toValue: Math.sign(g.dx) * 480, duration: 160, useNativeDriver: true }).start(() => dismiss(item.id));
5492
+ } else Animated27.spring(swipe, { toValue: 0, useNativeDriver: true }).start();
5116
5493
  }
5117
5494
  }),
5118
5495
  [swipe, item.id]
5119
5496
  );
5120
- React43.useEffect(() => {
5497
+ React44.useEffect(() => {
5121
5498
  if (item.tone === "success" || item.tone === "warning") haptic(item.tone);
5122
5499
  if (item.tone === "error") haptic("warning");
5123
5500
  }, [item.id]);
5124
- const [enter] = React43.useState(() => new Animated26.Value(reduce ? 1 : 0));
5125
- React43.useEffect(() => {
5501
+ const [enter] = React44.useState(() => new Animated27.Value(reduce ? 1 : 0));
5502
+ React44.useEffect(() => {
5126
5503
  if (reduce) enter.setValue(1);
5127
- else Animated26.timing(enter, { toValue: 1, duration: 220, useNativeDriver: true }).start();
5504
+ else Animated27.timing(enter, { toValue: 1, duration: 220, useNativeDriver: true }).start();
5128
5505
  }, [enter, reduce]);
5129
- React43.useEffect(() => {
5506
+ React44.useEffect(() => {
5130
5507
  AccessibilityInfo15.announceForAccessibility(item.description ? `${item.title}. ${item.description}` : item.title);
5131
5508
  }, [item.title, item.description]);
5132
5509
  const ms = item.duration ?? duration;
5133
- React43.useEffect(() => {
5510
+ React44.useEffect(() => {
5134
5511
  if (!Number.isFinite(ms)) return;
5135
5512
  const timer2 = setTimeout(() => dismiss(item.id), ms);
5136
5513
  return () => clearTimeout(timer2);
5137
5514
  }, [item.id, ms]);
5138
5515
  const edge = { success: theme.success, warning: theme.warning, error: theme.danger, info: theme.info, default: theme.borderDefault }[item.tone ?? "default"];
5139
- const text = /* @__PURE__ */ jsxs53(Fragment9, { children: [
5140
- item.icon ? /* @__PURE__ */ jsx62(View54, { "aria-hidden": true, children: item.icon }) : null,
5141
- /* @__PURE__ */ jsxs53(View54, { style: styles50.content, children: [
5142
- /* @__PURE__ */ jsx62(Txt, { variant: "label", numberOfLines: 2, children: item.title }),
5143
- item.description ? /* @__PURE__ */ jsx62(Txt, { variant: "caption", tone: "secondary", numberOfLines: 3, children: item.description }) : null
5516
+ const text = /* @__PURE__ */ jsxs54(Fragment9, { children: [
5517
+ item.icon ? /* @__PURE__ */ jsx63(View55, { "aria-hidden": true, children: item.icon }) : null,
5518
+ /* @__PURE__ */ jsxs54(View55, { style: styles51.content, children: [
5519
+ /* @__PURE__ */ jsx63(Txt, { variant: "label", numberOfLines: 2, children: item.title }),
5520
+ item.description ? /* @__PURE__ */ jsx63(Txt, { variant: "caption", tone: "secondary", numberOfLines: 3, children: item.description }) : null
5144
5521
  ] })
5145
5522
  ] });
5146
- const body = /* @__PURE__ */ jsxs53(Fragment9, { children: [
5147
- item.onPress ? /* @__PURE__ */ jsx62(
5148
- Pressable27,
5523
+ const body = /* @__PURE__ */ jsxs54(Fragment9, { children: [
5524
+ item.onPress ? /* @__PURE__ */ jsx63(
5525
+ Pressable28,
5149
5526
  {
5150
5527
  role: "button",
5151
5528
  onPress: () => {
5152
5529
  item.onPress?.();
5153
5530
  dismiss(item.id);
5154
5531
  },
5155
- style: ({ pressed }) => [styles50.main, { opacity: pressed ? 0.8 : 1 }],
5532
+ style: ({ pressed }) => [styles51.main, { opacity: pressed ? 0.8 : 1 }],
5156
5533
  children: text
5157
5534
  }
5158
- ) : /* @__PURE__ */ jsx62(View54, { style: styles50.main, children: text }),
5159
- item.action ? /* @__PURE__ */ jsx62(
5160
- Pressable27,
5535
+ ) : /* @__PURE__ */ jsx63(View55, { style: styles51.main, children: text }),
5536
+ item.action ? /* @__PURE__ */ jsx63(
5537
+ Pressable28,
5161
5538
  {
5162
5539
  role: "button",
5163
5540
  onPress: () => {
5164
5541
  item.action?.onPress();
5165
5542
  dismiss(item.id);
5166
5543
  },
5167
- style: [styles50.action, { backgroundColor: theme.accent, borderRadius: radius3.sm }],
5168
- children: /* @__PURE__ */ jsx62(Text20, { style: [styles50.actionLabel, { color: theme.onAccent }], children: item.action.label })
5544
+ style: [styles51.action, { backgroundColor: theme.accent, borderRadius: radius3.sm }],
5545
+ children: /* @__PURE__ */ jsx63(Text20, { style: [styles51.actionLabel, { color: theme.onAccent }], children: item.action.label })
5169
5546
  }
5170
5547
  ) : null,
5171
- /* @__PURE__ */ jsx62(Pressable27, { role: "button", "aria-label": closeLabel, hitSlop: 10, onPress: () => dismiss(item.id), style: styles50.close, children: /* @__PURE__ */ jsx62(Text20, { style: [styles50.cross, { color: theme.textSecondary }], children: "\xD7" }) })
5548
+ /* @__PURE__ */ jsx63(Pressable28, { role: "button", "aria-label": closeLabel, hitSlop: 10, onPress: () => dismiss(item.id), style: styles51.close, children: /* @__PURE__ */ jsx63(Text20, { style: [styles51.cross, { color: theme.textSecondary }], children: "\xD7" }) })
5172
5549
  ] });
5173
5550
  const frame = [
5174
- styles50.toast,
5551
+ styles51.toast,
5175
5552
  { backgroundColor: theme.surface2, borderColor: theme.borderDefault, borderLeftColor: edge, borderRadius: radius3.lg, shadowColor: theme.scrimStrong }
5176
5553
  ];
5177
5554
  const motion3 = { transform: [{ translateY: enter.interpolate({ inputRange: [0, 1], outputRange: [-8, 0] }) }, { translateX: swipe }] };
5178
- return /* @__PURE__ */ jsx62(Animated26.View, { "aria-live": "polite", style: motion3, ...drag.panHandlers, children: /* @__PURE__ */ jsx62(View54, { style: frame, children: body }) });
5555
+ return /* @__PURE__ */ jsx63(Animated27.View, { "aria-live": "polite", style: motion3, ...drag.panHandlers, children: /* @__PURE__ */ jsx63(View55, { style: frame, children: body }) });
5179
5556
  }
5180
5557
  function Toaster({ closeLabel, position = "top", offset = 12, duration = 6e3, max = 3 }) {
5181
- const all = React43.useSyncExternalStore(subscribe2, snapshot, snapshot);
5558
+ const all = React44.useSyncExternalStore(subscribe2, snapshot, snapshot);
5182
5559
  const shown = all.slice(-max);
5183
5560
  if (shown.length === 0) return null;
5184
- return /* @__PURE__ */ jsx62(View54, { pointerEvents: "box-none", style: [styles50.stack, position === "top" ? { top: offset } : { bottom: offset }], children: (position === "top" ? shown : [...shown].reverse()).map((item) => /* @__PURE__ */ jsx62(ToastView, { item, closeLabel, duration }, item.id)) });
5561
+ return /* @__PURE__ */ jsx63(View55, { pointerEvents: "box-none", style: [styles51.stack, position === "top" ? { top: offset } : { bottom: offset }], children: (position === "top" ? shown : [...shown].reverse()).map((item) => /* @__PURE__ */ jsx63(ToastView, { item, closeLabel, duration }, item.id)) });
5185
5562
  }
5186
- var styles50 = StyleSheet50.create({
5563
+ var styles51 = StyleSheet51.create({
5187
5564
  stack: { position: "absolute", left: 12, right: 12, gap: 8, zIndex: 100 },
5188
5565
  toast: {
5189
5566
  flexDirection: "row",
5190
5567
  alignItems: "center",
5191
5568
  gap: 10,
5192
5569
  padding: 12,
5193
- borderWidth: StyleSheet50.hairlineWidth,
5570
+ borderWidth: StyleSheet51.hairlineWidth,
5194
5571
  borderLeftWidth: 4,
5195
5572
  shadowOpacity: 0.3,
5196
5573
  shadowRadius: 16,
@@ -5206,15 +5583,15 @@ var styles50 = StyleSheet50.create({
5206
5583
  });
5207
5584
 
5208
5585
  // src/native/verified-badge.tsx
5209
- import { StyleSheet as StyleSheet51, View as View55 } from "react-native";
5210
- import Svg27, { Path as Path22 } from "react-native-svg";
5211
- import { jsx as jsx63, jsxs as jsxs54 } from "react/jsx-runtime";
5586
+ import { StyleSheet as StyleSheet52, View as View56 } from "react-native";
5587
+ import Svg28, { Path as Path23 } from "react-native-svg";
5588
+ import { jsx as jsx64, jsxs as jsxs55 } from "react/jsx-runtime";
5212
5589
  function VerifiedBadge({ label, showLabel, size = 16, on = "surface" }) {
5213
5590
  const { theme } = useTheme();
5214
- return /* @__PURE__ */ jsxs54(View55, { accessible: true, role: "img", "aria-label": label, style: styles51.row, children: [
5215
- /* @__PURE__ */ jsxs54(Svg27, { width: size, height: size, viewBox: "0 0 24 24", "aria-hidden": true, children: [
5216
- /* @__PURE__ */ jsx63(
5217
- Path22,
5591
+ return /* @__PURE__ */ jsxs55(View56, { accessible: true, role: "img", "aria-label": label, style: styles52.row, children: [
5592
+ /* @__PURE__ */ jsxs55(Svg28, { width: size, height: size, viewBox: "0 0 24 24", "aria-hidden": true, children: [
5593
+ /* @__PURE__ */ jsx64(
5594
+ Path23,
5218
5595
  {
5219
5596
  d: "M12 2.5l2.4 1.7 2.9-.1.9 2.8 2.3 1.8-.9 2.8.9 2.8-2.3 1.8-.9 2.8-2.9-.1L12 21.5l-2.4-1.7-2.9.1-.9-2.8-2.3-1.8.9-2.8-.9-2.8 2.3-1.8.9-2.8 2.9.1z",
5220
5597
  fill: theme.accent,
@@ -5222,12 +5599,12 @@ function VerifiedBadge({ label, showLabel, size = 16, on = "surface" }) {
5222
5599
  strokeWidth: 1.2
5223
5600
  }
5224
5601
  ),
5225
- /* @__PURE__ */ jsx63(Path22, { d: "M8.3 12.3l2.5 2.5 4.9-5.2", fill: "none", stroke: theme.onAccent, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round" })
5602
+ /* @__PURE__ */ jsx64(Path23, { d: "M8.3 12.3l2.5 2.5 4.9-5.2", fill: "none", stroke: theme.onAccent, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round" })
5226
5603
  ] }),
5227
- showLabel ? /* @__PURE__ */ jsx63(Txt, { variant: "caption", tone: on === "media" ? "onMedia" : "accent", style: styles51.text, children: label }) : null
5604
+ showLabel ? /* @__PURE__ */ jsx64(Txt, { variant: "caption", tone: on === "media" ? "onMedia" : "accent", style: styles52.text, children: label }) : null
5228
5605
  ] });
5229
5606
  }
5230
- var styles51 = StyleSheet51.create({ row: { flexDirection: "row", alignItems: "center", gap: 4 }, text: { fontWeight: "700" } });
5607
+ var styles52 = StyleSheet52.create({ row: { flexDirection: "row", alignItems: "center", gap: 4 }, text: { fontWeight: "700" } });
5231
5608
  export {
5232
5609
  ActionSheet,
5233
5610
  ActivityFeed,
@@ -5294,6 +5671,7 @@ export {
5294
5671
  Segmented,
5295
5672
  Select,
5296
5673
  Sheet,
5674
+ Showcase,
5297
5675
  Skeleton,
5298
5676
  Slider,
5299
5677
  Spinner,
@@ -5336,6 +5714,7 @@ export {
5336
5714
  latestBirthDate,
5337
5715
  monthNames,
5338
5716
  prefetchNeighbours,
5717
+ showcaseLabels,
5339
5718
  splitDuration,
5340
5719
  textStyles,
5341
5720
  timeSlots,