@krizaka/ui 3.7.1 → 3.9.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 (303) hide show
  1. package/README.md +14 -12
  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-HCNOOPZE.js → chunk-KVDB4GXV.js} +2 -2
  40. package/dist/{chunk-RUPNPMP3.js → chunk-OWC2LZD2.js} +11 -3
  41. package/dist/chunk-OWC2LZD2.js.map +1 -0
  42. package/dist/{chunk-FDCMBWUU.js → chunk-REPTKUJ6.js} +4 -4
  43. package/dist/chunk-REPTKUJ6.js.map +1 -0
  44. package/dist/{chunk-JZPVUJIX.js → chunk-UB2BI3AW.js} +1 -1
  45. package/dist/{chunk-JZPVUJIX.js.map → chunk-UB2BI3AW.js.map} +1 -1
  46. package/dist/code-block.d.ts +32 -10
  47. package/dist/code-block.js +51 -43
  48. package/dist/code-block.js.map +1 -1
  49. package/dist/combobox.d.ts +3 -3
  50. package/dist/combobox.js +4 -3
  51. package/dist/command.js +3 -2
  52. package/dist/command.js.map +1 -1
  53. package/dist/component-page.js.map +1 -1
  54. package/dist/confirm-button.d.ts +1 -1
  55. package/dist/confirm-button.js +2 -1
  56. package/dist/confirm-button.js.map +1 -1
  57. package/dist/continue-prompt.js +11 -3
  58. package/dist/continue-prompt.js.map +1 -1
  59. package/dist/data-table.js +7 -6
  60. package/dist/data-table.js.map +1 -1
  61. package/dist/date-picker.js +1 -1
  62. package/dist/dialog.js +3 -2
  63. package/dist/dialog.js.map +1 -1
  64. package/dist/file-upload.d.ts +12 -1
  65. package/dist/file-upload.js +73 -89
  66. package/dist/file-upload.js.map +1 -1
  67. package/dist/filter-bar.js +3 -2
  68. package/dist/{geometry-CbOU4rtL.d.ts → geometry-B2E8oFhg.d.ts} +1 -1
  69. package/dist/image-cropper.js +1 -1
  70. package/dist/index.d.ts +7 -5
  71. package/dist/index.js +26 -24
  72. package/dist/index.js.map +1 -1
  73. package/dist/list.js +1 -1
  74. package/dist/map.js +1 -1
  75. package/dist/map.js.map +1 -1
  76. package/dist/markdown.d.ts +38 -0
  77. package/dist/markdown.js +150 -0
  78. package/dist/markdown.js.map +1 -0
  79. package/dist/mascot-quote.d.ts +1 -1
  80. package/dist/mascot-quote.js.map +1 -1
  81. package/dist/mascot-state.d.ts +1 -1
  82. package/dist/mascot-state.js +1 -1
  83. package/dist/mascots.d.ts +2 -2
  84. package/dist/mascots.js +1 -1
  85. package/dist/match-dialog.js +2 -1
  86. package/dist/match-dialog.js.map +1 -1
  87. package/dist/media-capture.js +1 -1
  88. package/dist/native/map.js +1 -1
  89. package/dist/native/map.js.map +1 -1
  90. package/dist/native/markdown.d.ts +24 -0
  91. package/dist/native/markdown.js +200 -0
  92. package/dist/native/markdown.js.map +1 -0
  93. package/dist/native.d.ts +10 -14
  94. package/dist/native.js +383 -119
  95. package/dist/native.js.map +1 -1
  96. package/dist/recipes.d.ts +143 -0
  97. package/dist/recipes.js +180 -0
  98. package/dist/recipes.js.map +1 -0
  99. package/dist/search-field.js +2 -2
  100. package/dist/status-page.d.ts +1 -1
  101. package/dist/status-page.js.map +1 -1
  102. package/dist/swipe-deck.js +1 -1
  103. package/dist/tag-input.js +4 -3
  104. package/dist/tag-input.js.map +1 -1
  105. package/dist/tag-selector.js +2 -1
  106. package/dist/tag-selector.js.map +1 -1
  107. package/dist/theme.d.ts +1 -1
  108. package/dist/theme.js +2 -1
  109. package/dist/theme.js.map +1 -1
  110. package/dist/tree-view.js +1 -1
  111. package/dist/vertical-video.js +2 -1
  112. package/dist/vertical-video.js.map +1 -1
  113. package/dist/video-player.js +1 -1
  114. package/dist/video-trimmer.js +1 -1
  115. package/dist/virtual.js +2 -2
  116. package/package.json +49 -18
  117. package/registry/achievement.json +1 -1
  118. package/registry/action-bar.json +1 -1
  119. package/registry/activity-feed.json +1 -1
  120. package/registry/alert.json +1 -1
  121. package/registry/app-shell.json +135 -12
  122. package/registry/argument-card.json +1 -1
  123. package/registry/audio-player.json +2 -2
  124. package/registry/auth-layout.json +1 -1
  125. package/registry/avatar.json +1 -1
  126. package/registry/badge.json +9 -3
  127. package/registry/button.json +7 -2
  128. package/registry/card-grid.json +1 -1
  129. package/registry/card.json +8 -3
  130. package/registry/catalogue-page.json +1 -1
  131. package/registry/changelog-page.json +1 -1
  132. package/registry/chat.json +1 -1
  133. package/registry/checkbox.json +1 -1
  134. package/registry/chip-link.json +1 -1
  135. package/registry/chip.json +9 -3
  136. package/registry/choice-grid.json +1 -1
  137. package/registry/code-block.json +65 -21
  138. package/registry/combobox.json +4 -3
  139. package/registry/command.json +1 -1
  140. package/registry/component-page.json +4 -4
  141. package/registry/confirm-button.json +1 -1
  142. package/registry/contact-page.json +1 -1
  143. package/registry/continue-prompt.json +1 -1
  144. package/registry/countdown.json +1 -1
  145. package/registry/cta-panel.json +1 -1
  146. package/registry/dashboard-layout.json +1 -1
  147. package/registry/data-table.json +2 -2
  148. package/registry/date-picker.json +3 -3
  149. package/registry/decision-list.json +1 -1
  150. package/registry/description-list.json +1 -1
  151. package/registry/detail-layout.json +1 -1
  152. package/registry/dialog.json +1 -1
  153. package/registry/docs-article-page.json +1 -1
  154. package/registry/docs-hub-page.json +1 -1
  155. package/registry/docs-layout.json +1 -1
  156. package/registry/dropdown-menu.json +1 -1
  157. package/registry/empty-state.json +1 -1
  158. package/registry/error-page.json +1 -1
  159. package/registry/examples/app-shell/console.d.ts +4 -0
  160. package/registry/examples/app-shell/console.js +93 -0
  161. package/registry/examples/app-shell/console.tsx +103 -0
  162. package/registry/examples/badge/native/dot.dark.png +0 -0
  163. package/registry/examples/badge/native/dot.light.png +0 -0
  164. package/registry/examples/badge/native/scrim.dark.png +0 -0
  165. package/registry/examples/badge/native/scrim.light.png +0 -0
  166. package/registry/examples/badge/native/tones.dark.png +0 -0
  167. package/registry/examples/badge/native/tones.light.png +0 -0
  168. package/registry/examples/card/native/default.dark.png +0 -0
  169. package/registry/examples/card/native/default.light.png +0 -0
  170. package/registry/examples/card/native/elevated.light.png +0 -0
  171. package/registry/examples/chip/native/multiple.dark.png +0 -0
  172. package/registry/examples/chip/native/multiple.light.png +0 -0
  173. package/registry/examples/chip/native/removable.dark.png +0 -0
  174. package/registry/examples/chip/native/removable.light.png +0 -0
  175. package/registry/examples/chip/native/single.dark.png +0 -0
  176. package/registry/examples/chip/native/single.light.png +0 -0
  177. package/registry/examples/chip/native/toggle.dark.png +0 -0
  178. package/registry/examples/chip/native/toggle.light.png +0 -0
  179. package/registry/examples/code-block/annotated.d.ts +4 -0
  180. package/registry/examples/code-block/annotated.js +31 -0
  181. package/registry/examples/code-block/annotated.tsx +26 -0
  182. package/registry/examples/component-page/button.tsx +1 -1
  183. package/registry/examples/form/native/amount.dark.png +0 -0
  184. package/registry/examples/form/native/amount.light.png +0 -0
  185. package/registry/examples/landing-page/krizaka.js +1 -1
  186. package/registry/examples/landing-page/krizaka.tsx +1 -1
  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/mascots/flock.tsx +1 -1
  204. package/registry/examples/profile-card/match.js +1 -1
  205. package/registry/examples/profile-card/match.tsx +1 -1
  206. package/registry/examples/recipes/tone-chip.d.ts +4 -0
  207. package/registry/examples/recipes/tone-chip.js +46 -0
  208. package/registry/examples/recipes/tone-chip.tsx +32 -0
  209. package/registry/examples/screen/native/profile.dark.png +0 -0
  210. package/registry/examples/screen/native/profile.light.png +0 -0
  211. package/registry/examples/status-page/building.js +1 -1
  212. package/registry/examples/status-page/building.tsx +1 -1
  213. package/registry/examples/tag-selector/native/interests.dark.png +0 -0
  214. package/registry/examples/tag-selector/native/interests.light.png +0 -0
  215. package/registry/field.json +1 -1
  216. package/registry/file-upload.json +8 -3
  217. package/registry/filter-bar.json +1 -1
  218. package/registry/form.json +2 -2
  219. package/registry/gallery-page.json +1 -1
  220. package/registry/glow-card.json +1 -1
  221. package/registry/goal-gauge.json +1 -1
  222. package/registry/how-it-works-page.json +1 -1
  223. package/registry/image-cropper.json +2 -2
  224. package/registry/index.json +77 -17
  225. package/registry/iso.json +1 -1
  226. package/registry/kanban.json +1 -1
  227. package/registry/kbd.json +1 -1
  228. package/registry/landing-page.json +3 -3
  229. package/registry/landscape.json +1 -1
  230. package/registry/legal-page.json +1 -1
  231. package/registry/link-card.json +1 -1
  232. package/registry/list.json +2 -2
  233. package/registry/loader.json +4 -4
  234. package/registry/longform-page.json +1 -1
  235. package/registry/map.json +3 -3
  236. package/registry/markdown.json +266 -0
  237. package/registry/marketing-layout.json +1 -1
  238. package/registry/marquee.json +1 -1
  239. package/registry/mascot-quote.json +1 -1
  240. package/registry/mascot-state.json +1 -1
  241. package/registry/mascots.json +5 -5
  242. package/registry/match-dialog.json +1 -1
  243. package/registry/media-capture.json +2 -2
  244. package/registry/meter.json +1 -1
  245. package/registry/nav-bar.json +1 -1
  246. package/registry/number-ticker.json +1 -1
  247. package/registry/page-header.json +1 -1
  248. package/registry/page-hero.json +1 -1
  249. package/registry/page.json +1 -1
  250. package/registry/pagination.json +1 -1
  251. package/registry/photo-grid.json +1 -1
  252. package/registry/pointer-light.json +1 -1
  253. package/registry/popover.json +1 -1
  254. package/registry/pricing-page.json +1 -1
  255. package/registry/product-page.json +3 -3
  256. package/registry/profile-card.json +2 -2
  257. package/registry/progress.json +1 -1
  258. package/registry/promise-card.json +1 -1
  259. package/registry/radio-group.json +1 -1
  260. package/registry/recipes.json +99 -0
  261. package/registry/scroll-stage.json +1 -1
  262. package/registry/search-field.json +4 -3
  263. package/registry/section-backdrop.json +1 -1
  264. package/registry/separator.json +1 -1
  265. package/registry/settings-layout.json +1 -1
  266. package/registry/skeleton.json +1 -1
  267. package/registry/skip-link.json +1 -1
  268. package/registry/slider.json +1 -1
  269. package/registry/slot.json +1 -1
  270. package/registry/spinner.json +1 -1
  271. package/registry/split-view.json +1 -1
  272. package/registry/stage-banner.json +1 -1
  273. package/registry/stat.json +1 -1
  274. package/registry/status-page.json +7 -7
  275. package/registry/step-progress.json +1 -1
  276. package/registry/stepper.json +1 -1
  277. package/registry/swipe-deck.json +2 -2
  278. package/registry/switch.json +1 -1
  279. package/registry/tabs.json +1 -1
  280. package/registry/tag-input.json +2 -2
  281. package/registry/tag-selector.json +1 -1
  282. package/registry/terminal-replay.json +1 -1
  283. package/registry/theme.json +1 -1
  284. package/registry/toast.json +1 -1
  285. package/registry/toc.json +1 -1
  286. package/registry/tooltip.json +1 -1
  287. package/registry/tree-view.json +2 -2
  288. package/registry/verified-badge.json +1 -1
  289. package/registry/vertical-video.json +2 -2
  290. package/registry/video-player.json +2 -2
  291. package/registry/video-trimmer.json +2 -2
  292. package/registry/virtual.json +2 -2
  293. package/dist/button-BMAO7dKF.d.ts +0 -114
  294. package/dist/chunk-BRKMQ6JV.js.map +0 -1
  295. package/dist/chunk-FDCMBWUU.js.map +0 -1
  296. package/dist/chunk-LCZXS6AK.js.map +0 -1
  297. package/dist/chunk-RUPNPMP3.js.map +0 -1
  298. package/dist/chunk-UOMP6VOZ.js.map +0 -1
  299. package/dist/chunk-YH4LMWRU.js.map +0 -1
  300. package/dist/chunk-Z6FUPB3Q.js.map +0 -1
  301. /package/dist/{chunk-ND3L5VHT.js.map → chunk-5Z7FWCV2.js.map} +0 -0
  302. /package/dist/{chunk-ZKVQGXLD.js.map → chunk-FKBHWS4N.js.map} +0 -0
  303. /package/dist/{chunk-HCNOOPZE.js.map → chunk-KVDB4GXV.js.map} +0 -0
package/dist/native.js CHANGED
@@ -305,7 +305,7 @@ var marks = /* @__PURE__ */ Object.freeze({
305
305
  "#f472b6"
306
306
  ]
307
307
  ],
308
- "yazakia": [
308
+ "yasakia": [
309
309
  [
310
310
  "0%",
311
311
  "#079d61"
@@ -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);
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;
685
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;
@@ -2688,14 +2950,14 @@ function OrochiaMark({ size = 48, animated = true, title, neutral: neutralProp }
2688
2950
  ] });
2689
2951
  }
2690
2952
 
2691
- // src/native/YazakiaMark.tsx
2953
+ // src/native/YasakiaMark.tsx
2692
2954
  import React21 from "react";
2693
2955
  import { View as View24 } from "react-native";
2694
2956
  import Svg11, { Circle as Circle5, Defs as Defs6, LinearGradient as LinearGradient6, Path as Path9, RadialGradient as RadialGradient4, Stop as Stop6 } from "react-native-svg";
2695
2957
 
2696
- // src/marks/yazakia-geometry.ts
2697
- var turquoise = marks.yazakia[marks.yazakia.length - 1][1];
2698
- var YAZAKIA = {
2958
+ // src/marks/yasakia-geometry.ts
2959
+ var turquoise = marks.yasakia[marks.yasakia.length - 1][1];
2960
+ var YASAKIA = {
2699
2961
  viewBox: "0 0 400 400",
2700
2962
  croppedViewBox: "80 80 240 240",
2701
2963
  center: 200,
@@ -2708,7 +2970,7 @@ var YAZAKIA = {
2708
2970
  shade: { color: "#000", opacity: 0.22 },
2709
2971
  /** Where the bubbles overlap: the core, lit from above. */
2710
2972
  lens: { d: "M200 112.6 A80 80 0 0 1 200 255.4 A80 80 0 0 1 200 112.6 Z", y1: 112.6, y2: 255.4 },
2711
- gradient: { x1: 110, y1: 300, x2: 290, y2: 100, stops: marks.yazakia },
2973
+ gradient: { x1: 110, y1: 300, x2: 290, y2: 100, stops: marks.yasakia },
2712
2974
  /** The light on the lens: bright at the top, fading down. */
2713
2975
  highlight: { color: "#f0fdfa", from: 0.75, to: 0.2 },
2714
2976
  /** The pair: two nodes on the orbit, opposite each other, that turn with it. */
@@ -2720,51 +2982,52 @@ var YAZAKIA = {
2720
2982
  ring: { r: 134, width: 1 }
2721
2983
  };
2722
2984
 
2723
- // src/native/YazakiaMark.tsx
2985
+ // src/native/YasakiaMark.tsx
2724
2986
  import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
2725
- function YazakiaMark({ size = 48, animated = true, title, neutral }) {
2987
+ function YasakiaMark({ size = 48, animated = true, title, neutral }) {
2726
2988
  const { theme } = useTheme();
2727
2989
  const { Animated: Animated27, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
2728
2990
  const id = useSvgId("yzm");
2729
- const viewBox = size < 48 ? YAZAKIA.croppedViewBox : YAZAKIA.viewBox;
2991
+ const viewBox = size < 48 ? YASAKIA.croppedViewBox : YASAKIA.viewBox;
2730
2992
  const stroke = neutral ?? theme.textMuted;
2731
- const gradient = /* @__PURE__ */ jsx28(LinearGradient6, { id: `${id}a`, gradientUnits: "userSpaceOnUse", x1: YAZAKIA.gradient.x1, y1: YAZAKIA.gradient.y1, x2: YAZAKIA.gradient.x2, y2: YAZAKIA.gradient.y2, children: YAZAKIA.gradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx28(Stop6, { offset, stopColor: color }, offset)) });
2993
+ const gradient = /* @__PURE__ */ jsx28(LinearGradient6, { id: `${id}a`, gradientUnits: "userSpaceOnUse", x1: YASAKIA.gradient.x1, y1: YASAKIA.gradient.y1, x2: YASAKIA.gradient.x2, y2: YASAKIA.gradient.y2, children: YASAKIA.gradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx28(Stop6, { offset, stopColor: color }, offset)) });
2732
2994
  const fill = `url(#${id}a)`;
2733
2995
  return /* @__PURE__ */ jsxs25(View24, { style: { width: size, height: size }, ...markA11y(title), children: [
2734
2996
  /* @__PURE__ */ jsxs25(Svg11, { viewBox, style: layer, children: [
2735
2997
  /* @__PURE__ */ jsxs25(Defs6, { children: [
2736
2998
  /* @__PURE__ */ jsxs25(RadialGradient4, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
2737
- /* @__PURE__ */ jsx28(Stop6, { offset: "0%", stopColor: YAZAKIA.glow.color, stopOpacity: YAZAKIA.glow.opacity }),
2738
- /* @__PURE__ */ jsx28(Stop6, { offset: "100%", stopColor: YAZAKIA.glow.color, stopOpacity: 0 })
2999
+ /* @__PURE__ */ jsx28(Stop6, { offset: "0%", stopColor: YASAKIA.glow.color, stopOpacity: YASAKIA.glow.opacity }),
3000
+ /* @__PURE__ */ jsx28(Stop6, { offset: "100%", stopColor: YASAKIA.glow.color, stopOpacity: 0 })
2739
3001
  ] }),
2740
3002
  gradient
2741
3003
  ] }),
2742
- size >= 48 ? /* @__PURE__ */ jsx28(Circle5, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: 190, fill: `url(#${id}g)` }) : null,
2743
- /* @__PURE__ */ jsx28(Circle5, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: YAZAKIA.ring.r, stroke, strokeWidth: YAZAKIA.ring.width, opacity: 0.35, fill: "none" }),
2744
- YAZAKIA.voices.map((v, i) => /* @__PURE__ */ jsxs25(React21.Fragment, { children: [
3004
+ size >= 48 ? /* @__PURE__ */ jsx28(Circle5, { cx: YASAKIA.center, cy: YASAKIA.center, r: 190, fill: `url(#${id}g)` }) : null,
3005
+ /* @__PURE__ */ jsx28(Circle5, { cx: YASAKIA.center, cy: YASAKIA.center, r: YASAKIA.ring.r, stroke, strokeWidth: YASAKIA.ring.width, opacity: 0.35, fill: "none" }),
3006
+ YASAKIA.voices.map((v, i) => /* @__PURE__ */ jsxs25(React21.Fragment, { children: [
2745
3007
  /* @__PURE__ */ jsx28(Path9, { d: v.body, fill }),
2746
3008
  /* @__PURE__ */ jsx28(Path9, { d: v.tail, fill }),
2747
- i === 0 ? /* @__PURE__ */ jsx28(Path9, { d: `${v.body} ${v.tail}`, fill: YAZAKIA.shade.color, opacity: YAZAKIA.shade.opacity }) : null
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
3012
  /* @__PURE__ */ jsx28(Animated27.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs25(Svg11, { viewBox, style: layer, children: [
2751
3013
  /* @__PURE__ */ jsx28(Defs6, { children: gradient }),
2752
- /* @__PURE__ */ jsx28(Circle5, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: YAZAKIA.orbit.r, stroke, strokeWidth: YAZAKIA.orbit.width, strokeDasharray: YAZAKIA.orbit.dash, opacity: 0.6, fill: "none" }),
2753
- YAZAKIA.pair.at.map(([cx, cy]) => /* @__PURE__ */ jsx28(Circle5, { cx, cy, r: YAZAKIA.pair.r, fill }, cx))
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" }),
3015
+ YASAKIA.pair.at.map(([cx, cy]) => /* @__PURE__ */ jsx28(Circle5, { cx, cy, r: YASAKIA.pair.r, fill }, cx))
2754
3016
  ] }) }),
2755
3017
  /* @__PURE__ */ jsx28(Animated27.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs25(Svg11, { viewBox, style: layer, children: [
2756
3018
  /* @__PURE__ */ jsxs25(Defs6, { children: [
2757
3019
  gradient,
2758
- /* @__PURE__ */ jsxs25(LinearGradient6, { id: `${id}l`, gradientUnits: "userSpaceOnUse", x1: 0, y1: YAZAKIA.lens.y1, x2: 0, y2: YAZAKIA.lens.y2, children: [
2759
- /* @__PURE__ */ jsx28(Stop6, { offset: "0%", stopColor: YAZAKIA.highlight.color, stopOpacity: YAZAKIA.highlight.from }),
2760
- /* @__PURE__ */ jsx28(Stop6, { offset: "100%", stopColor: YAZAKIA.highlight.color, stopOpacity: YAZAKIA.highlight.to })
3020
+ /* @__PURE__ */ jsxs25(LinearGradient6, { id: `${id}l`, gradientUnits: "userSpaceOnUse", x1: 0, y1: YASAKIA.lens.y1, x2: 0, y2: YASAKIA.lens.y2, children: [
3021
+ /* @__PURE__ */ jsx28(Stop6, { offset: "0%", stopColor: YASAKIA.highlight.color, stopOpacity: YASAKIA.highlight.from }),
3022
+ /* @__PURE__ */ jsx28(Stop6, { offset: "100%", stopColor: YASAKIA.highlight.color, stopOpacity: YASAKIA.highlight.to })
2761
3023
  ] })
2762
3024
  ] }),
2763
- /* @__PURE__ */ jsx28(Path9, { d: YAZAKIA.lens.d, fill }),
2764
- /* @__PURE__ */ jsx28(Path9, { d: YAZAKIA.lens.d, fill: `url(#${id}l)` })
3025
+ /* @__PURE__ */ jsx28(Path9, { d: YASAKIA.lens.d, fill }),
3026
+ /* @__PURE__ */ jsx28(Path9, { d: YASAKIA.lens.d, fill: `url(#${id}l)` })
2765
3027
  ] }) })
2766
3028
  ] });
2767
3029
  }
3030
+ var YazakiaMark = YasakiaMark;
2768
3031
 
2769
3032
  // src/native/YororisMark.tsx
2770
3033
  import { View as View25 } from "react-native";
@@ -2846,7 +3109,7 @@ import { jsx as jsx30 } from "react/jsx-runtime";
2846
3109
  function ProductMark({ id, ...props }) {
2847
3110
  if (id === "krizaka") return /* @__PURE__ */ jsx30(KrizakaMark, { ...props });
2848
3111
  if (id === "orazaka") return /* @__PURE__ */ jsx30(OrazakaMark, { ...props });
2849
- if (id === "yazakia") return /* @__PURE__ */ jsx30(YazakiaMark, { ...props });
3112
+ if (id === "yasakia" || id === "yazakia") return /* @__PURE__ */ jsx30(YasakiaMark, { ...props });
2850
3113
  if (id === "yororis") return /* @__PURE__ */ jsx30(YororisMark, { ...props });
2851
3114
  return /* @__PURE__ */ jsx30(OrochiaMark, { ...props });
2852
3115
  }
@@ -2918,10 +3181,10 @@ function Loader({ label, status = "loading", successLabel, errorLabel, value, et
2918
3181
  };
2919
3182
  }, [waiting, status, endDuration]);
2920
3183
  const phase = waiting ? "loading" : ending;
2921
- const words = phase === "success" ? successLabel ?? label : phase === "error" ? errorLabel ?? label : label;
3184
+ const words2 = phase === "success" ? successLabel ?? label : phase === "error" ? errorLabel ?? label : label;
2922
3185
  React22.useEffect(() => {
2923
- if (phase) AccessibilityInfo7.announceForAccessibility(words);
2924
- }, [phase, words]);
3186
+ if (phase) AccessibilityInfo7.announceForAccessibility(words2);
3187
+ }, [phase, words2]);
2925
3188
  if (!phase) return null;
2926
3189
  const known = phase === "loading" && typeof value === "number" && Number.isFinite(value);
2927
3190
  const detail = phase === "loading" ? [known ? `${Math.round(Math.min(1, Math.max(0, value)) * 100)} %` : null, eta].filter(Boolean).join(" \xB7 ") : "";
@@ -2929,11 +3192,11 @@ function Loader({ label, status = "loading", successLabel, errorLabel, value, et
2929
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: [
2930
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] }),
2931
3194
  /* @__PURE__ */ jsxs27(View26, { style: stacked ? styles24.center : styles24.text, children: [
2932
- /* @__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 }),
2933
3196
  detail ? /* @__PURE__ */ jsx31(Txt, { variant: "caption", tone: "secondary", style: stacked ? styles24.centered : null, children: detail }) : null
2934
3197
  ] })
2935
3198
  ] });
2936
- 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" };
2937
3200
  if (variant === "overlay" || variant === "page")
2938
3201
  return /* @__PURE__ */ jsx31(View26, { ...a11y, style: [StyleSheet24.absoluteFill, styles24.cover, variant === "page" ? { backgroundColor: alpha(theme.surface0, 0.86) } : null, style], children: box });
2939
3202
  return /* @__PURE__ */ jsx31(View26, { ...a11y, style: [variant === "block" ? styles24.block : null, style], children: box });
@@ -3320,9 +3583,9 @@ function Meter({ label, value = 0, min = 0, max = 100, valueText, thresholds, op
3320
3583
  const ratio = Math.min(1, Math.max(0, (value - min) / span));
3321
3584
  const level = !thresholds ? "ok" : ratio >= thresholds.high ? optimum === "low" ? "danger" : "success" : ratio >= thresholds.low ? "warning" : optimum === "low" ? "success" : "danger";
3322
3585
  const tone3 = { ok: theme.accent, success: theme.success, warning: theme.warning, danger: theme.danger }[level];
3323
- const words = valueText ?? `${Math.round(ratio * 100)} %`;
3586
+ const words2 = valueText ?? `${Math.round(ratio * 100)} %`;
3324
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)} %` }));
3325
- 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 };
3326
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: [
3327
3590
  /* @__PURE__ */ jsx35(View30, { style: [styles27.swatch, { backgroundColor: p.color }] }),
3328
3591
  /* @__PURE__ */ jsx35(Txt, { variant: "caption", children: p.label }),
@@ -3352,7 +3615,7 @@ function Meter({ label, value = 0, min = 0, max = 100, valueText, thresholds, op
3352
3615
  return /* @__PURE__ */ jsxs31(View30, { accessible: true, ...a11y, style: [styles27.root, style], children: [
3353
3616
  showLabel ? /* @__PURE__ */ jsxs31(View30, { style: styles27.header, "aria-hidden": true, children: [
3354
3617
  /* @__PURE__ */ jsx35(Txt, { variant: "caption", numberOfLines: 1, style: styles27.caption, children: label }),
3355
- !parts ? /* @__PURE__ */ jsx35(Txt, { variant: "caption", tone: "secondary", children: words }) : null
3618
+ !parts ? /* @__PURE__ */ jsx35(Txt, { variant: "caption", tone: "secondary", children: words2 }) : null
3356
3619
  ] }) : null,
3357
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 }] }) }),
3358
3621
  legend
@@ -3778,7 +4041,7 @@ import * as React31 from "react";
3778
4041
  import { Animated as Animated17, StyleSheet as StyleSheet33, View as View37 } from "react-native";
3779
4042
  import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
3780
4043
  var ratioOf = (value, max = 100) => Math.min(1, Math.max(0, value / (max || 1)));
3781
- function Bar({ label, ratio, words, animated, delay }) {
4044
+ function Bar({ label, ratio, words: words2, animated, delay }) {
3782
4045
  const { theme } = useTheme();
3783
4046
  const t = useEntrance(animated, delay, 900);
3784
4047
  const [width, setWidth] = React31.useState(0);
@@ -3792,7 +4055,7 @@ function Bar({ label, ratio, words, animated, delay }) {
3792
4055
  "aria-valuemin": 0,
3793
4056
  "aria-valuemax": 100,
3794
4057
  "aria-valuenow": Math.round(ratio * 100),
3795
- "aria-valuetext": words,
4058
+ "aria-valuetext": words2,
3796
4059
  onLayout: (e) => setWidth(e.nativeEvent.layout.width),
3797
4060
  style: [styles33.track, { backgroundColor: theme.surface3 }],
3798
4061
  children: /* @__PURE__ */ jsx43(Animated17.View, { style: [styles33.fill, { width: `${ratio * 100}%`, backgroundColor: theme.accent, transform: [{ translateX }] }] })
@@ -3815,13 +4078,13 @@ function ProfileCard({ visual, name, statLabel, value = 100, valueText, stats, c
3815
4078
  statLabel ? /* @__PURE__ */ jsx43(Bar, { label: statLabel, ratio, words: valueText ?? `${Math.round(ratio * 100)} %`, animated, delay: 200 }) : null,
3816
4079
  stats?.map((s, i) => {
3817
4080
  const r = ratioOf(s.value, s.max);
3818
- const words = s.valueText ?? `${Math.round(r * 100)} %`;
4081
+ const words2 = s.valueText ?? `${Math.round(r * 100)} %`;
3819
4082
  return /* @__PURE__ */ jsxs38(View37, { style: styles33.stat, children: [
3820
4083
  /* @__PURE__ */ jsxs38(View37, { "aria-hidden": true, style: styles33.statHead, children: [
3821
4084
  /* @__PURE__ */ jsx43(Txt, { variant: "caption", tone: "secondary", children: s.label }),
3822
- /* @__PURE__ */ jsx43(Txt, { variant: "caption", children: words })
4085
+ /* @__PURE__ */ jsx43(Txt, { variant: "caption", children: words2 })
3823
4086
  ] }),
3824
- /* @__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 })
3825
4088
  ] }, s.label);
3826
4089
  }),
3827
4090
  caption ? /* @__PURE__ */ jsx43(Txt, { variant: "caption", tone: "secondary", style: styles33.caption, children: caption }) : null,
@@ -4146,6 +4409,7 @@ function Screen({ header, footer, children, scroll = true, keyboard = true, padd
4146
4409
  var styles37 = StyleSheet37.create({ flex: { flex: 1 } });
4147
4410
 
4148
4411
  // src/native/search-field.tsx
4412
+ import { useDebouncedCallback } from "@krizaka/pacer/react";
4149
4413
  import * as React35 from "react";
4150
4414
  import { Pressable as Pressable19, StyleSheet as StyleSheet38, TextInput as TextInput6, View as View42 } from "react-native";
4151
4415
  import Svg22, { Circle as Circle12, Path as Path18 } from "react-native-svg";
@@ -4156,13 +4420,12 @@ function SearchField({ label, value, defaultValue = "", onValueChange, onSearch,
4156
4420
  const { theme, radius: radius3 } = useTheme();
4157
4421
  const [own, setOwn] = React35.useState(defaultValue);
4158
4422
  const query = value ?? own;
4159
- const timer2 = React35.useRef(void 0);
4160
- React35.useEffect(() => () => clearTimeout(timer2.current), []);
4423
+ const search = useDebouncedCallback((next) => onSearch?.(next), debounce);
4161
4424
  const change = (next) => {
4162
4425
  if (value === void 0) setOwn(next);
4163
4426
  onValueChange?.(next);
4164
- clearTimeout(timer2.current);
4165
- if (onSearch) timer2.current = setTimeout(() => onSearch(next), debounce);
4427
+ search.cancel();
4428
+ if (onSearch) search(next);
4166
4429
  };
4167
4430
  const field = /* @__PURE__ */ jsxs43(View42, { style: [styles38.frame, { borderRadius: radius3.md, borderColor: theme.borderDefault, backgroundColor: theme.surface2 }, style], children: [
4168
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: [
@@ -4184,7 +4447,7 @@ function SearchField({ label, value, defaultValue = "", onValueChange, onSearch,
4184
4447
  clearButtonMode: "never",
4185
4448
  onChangeText: change,
4186
4449
  onSubmitEditing: () => {
4187
- clearTimeout(timer2.current);
4450
+ search.cancel();
4188
4451
  onSearch?.(query);
4189
4452
  onSubmit?.(query);
4190
4453
  },
@@ -4553,14 +4816,14 @@ import Svg24, { Path as Path19 } from "react-native-svg";
4553
4816
  import { jsx as jsx54, jsxs as jsxs45 } from "react/jsx-runtime";
4554
4817
  function StepProgress({ step, total, label, backLabel, onBack, trailing, style }) {
4555
4818
  const { theme, insets } = useTheme();
4556
- const words = label(step, total);
4819
+ const words2 = label(step, total);
4557
4820
  return /* @__PURE__ */ jsxs45(View46, { style: [styles42.root, { paddingTop: insets.top + 8 }, style], children: [
4558
4821
  /* @__PURE__ */ jsxs45(View46, { style: styles42.row, children: [
4559
4822
  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 }),
4560
- /* @__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)) }),
4823
+ /* @__PURE__ */ jsx54(View46, { accessible: true, role: "progressbar", "aria-label": words2, "aria-valuemin": 1, "aria-valuemax": total, "aria-valuenow": step, "aria-valuetext": words2, style: styles42.bars, children: Array.from({ length: total }, (_, i) => /* @__PURE__ */ jsx54(View46, { style: [styles42.bar, { backgroundColor: i < step ? theme.accent : theme.surface3 }] }, i)) }),
4561
4824
  /* @__PURE__ */ jsx54(View46, { style: styles42.trailing, children: trailing })
4562
4825
  ] }),
4563
- /* @__PURE__ */ jsx54(Txt, { variant: "caption", tone: "secondary", style: styles42.words, "aria-hidden": true, children: words })
4826
+ /* @__PURE__ */ jsx54(Txt, { variant: "caption", tone: "secondary", style: styles42.words, "aria-hidden": true, children: words2 })
4564
4827
  ] });
4565
4828
  }
4566
4829
  var styles42 = StyleSheet42.create({
@@ -4580,7 +4843,7 @@ import { jsx as jsx55, jsxs as jsxs46 } from "react/jsx-runtime";
4580
4843
  var WORDS = { done: "done", current: "in progress", upcoming: "to come", error: "failed" };
4581
4844
  function Stepper({ steps, current = 0, orientation = "vertical", statusLabels, "aria-label": label, style }) {
4582
4845
  const { theme } = useTheme();
4583
- const words = { ...WORDS, ...statusLabels };
4846
+ const words2 = { ...WORDS, ...statusLabels };
4584
4847
  const vertical = orientation === "vertical";
4585
4848
  return /* @__PURE__ */ jsx55(View47, { role: "list", "aria-label": label, style: [vertical ? styles43.column : styles43.row, style], children: steps.map((step, i) => {
4586
4849
  const status = step.status ?? (i < current ? "done" : i === current ? "current" : "upcoming");
@@ -4590,7 +4853,7 @@ function Stepper({ steps, current = 0, orientation = "vertical", statusLabels, "
4590
4853
  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
4591
4854
  ] });
4592
4855
  const connector = !last ? /* @__PURE__ */ jsx55(View47, { "aria-hidden": true, style: [vertical ? styles43.vLine : styles43.hLine, { backgroundColor: status === "done" ? theme.accent : theme.borderDefault }] }) : null;
4593
- return /* @__PURE__ */ jsxs46(View47, { role: "listitem", accessible: true, "aria-label": `${step.title}, ${words[status]}`, style: vertical ? styles43.vStep : styles43.hStep, children: [
4856
+ return /* @__PURE__ */ jsxs46(View47, { role: "listitem", accessible: true, "aria-label": `${step.title}, ${words2[status]}`, style: vertical ? styles43.vStep : styles43.hStep, children: [
4594
4857
  /* @__PURE__ */ jsxs46(View47, { style: vertical ? styles43.vRail : styles43.hRail, children: [
4595
4858
  node,
4596
4859
  connector
@@ -4678,7 +4941,7 @@ function PersonCard({ photos, name, age, badge, meta, bio, footer, photoLabel =
4678
4941
  }
4679
4942
  );
4680
4943
  }
4681
- function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty, labels, hideButtons, style }) {
4944
+ function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty: empty2, labels, hideButtons, style }) {
4682
4945
  const { theme, haptic } = useTheme();
4683
4946
  const reduce = useReducedMotion();
4684
4947
  const { width } = useWindowDimensions2();
@@ -4729,7 +4992,7 @@ function SwipeDeck({ items: items2, getId, renderCard, onSwipe, empty, labels, h
4729
4992
  );
4730
4993
  return /* @__PURE__ */ jsxs47(View48, { style: [styles44.deck, style], children: [
4731
4994
  /* @__PURE__ */ jsxs47(View48, { style: styles44.stack, children: [
4732
- !top ? empty ?? null : null,
4995
+ !top ? empty2 ?? null : null,
4733
4996
  items2.slice(0, 2).reverse().map((item) => {
4734
4997
  const isTop = item === top;
4735
4998
  return /* @__PURE__ */ jsxs47(
@@ -5317,6 +5580,7 @@ export {
5317
5580
  Wheel,
5318
5581
  WheelDivider,
5319
5582
  WheelPicker,
5583
+ YasakiaMark,
5320
5584
  YazakiaMark,
5321
5585
  YororisMark,
5322
5586
  addDays,