@btndprojects/loam-ui-native 0.1.0 → 0.2.1

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 (263) hide show
  1. package/README.md +56 -0
  2. package/dist/accordion/index.js +5 -3
  3. package/dist/adaptive/index.js +6 -2
  4. package/dist/alert/index.js +5 -2
  5. package/dist/analyzer/index.js +9 -6
  6. package/dist/announcement/index.js +8 -5
  7. package/dist/audio-player/index.js +5 -3
  8. package/dist/avatar/index.js +5 -2
  9. package/dist/avatar-group/index.js +7 -3
  10. package/dist/badge/index.js +7 -4
  11. package/dist/banner/index.js +5 -2
  12. package/dist/board/index.js +11 -6
  13. package/dist/button/index.js +6 -3
  14. package/dist/camera-permission/index.js +15 -12
  15. package/dist/capture-result/index.js +19 -16
  16. package/dist/card/index.js +6 -3
  17. package/dist/card-form/index.js +12 -8
  18. package/dist/carousel/index.js +4 -2
  19. package/dist/chart/index.js +8 -5
  20. package/dist/charts/index.js +8 -6
  21. package/dist/chat/index.js +16 -0
  22. package/dist/checkbox/index.js +6 -4
  23. package/dist/checklist/index.js +11 -8
  24. package/dist/checkout/index.js +16 -11
  25. package/dist/chip/index.js +7 -4
  26. package/dist/{chunk-XNUVB5OL.js → chunk-2OLKPG4E.js} +92 -28
  27. package/dist/{chunk-RUZHTGKB.js → chunk-2PKYGLQ6.js} +71 -40
  28. package/dist/{chunk-UC2WGUP3.js → chunk-2SWKL3AJ.js} +91 -252
  29. package/dist/{chunk-AI4DWZCD.js → chunk-2SY63FCH.js} +63 -16
  30. package/dist/{chunk-F5XNPWS7.js → chunk-2TXERVVA.js} +92 -35
  31. package/dist/chunk-36EC2T6P.js +581 -0
  32. package/dist/chunk-3DUWIYV5.js +437 -0
  33. package/dist/{chunk-RGQWWKLA.js → chunk-3QMEOFW5.js} +275 -71
  34. package/dist/chunk-3WEZCGHX.js +265 -0
  35. package/dist/chunk-46MMSDGL.js +194 -0
  36. package/dist/{chunk-7O2FMUPT.js → chunk-4IZXHVFJ.js} +297 -92
  37. package/dist/{chunk-LAECSR4H.js → chunk-5LAAAXFP.js} +14 -8
  38. package/dist/{chunk-2A5NIQAK.js → chunk-5RENVKBQ.js} +134 -46
  39. package/dist/{chunk-2ZZ7TDJ4.js → chunk-5UTRIXQ6.js} +37 -31
  40. package/dist/{chunk-LOE5YNN3.js → chunk-5VFZRGVD.js} +37 -10
  41. package/dist/{chunk-52X2VYTD.js → chunk-67IZZ2MJ.js} +115 -60
  42. package/dist/{chunk-UYG5L34B.js → chunk-6YAQBXB3.js} +10 -4
  43. package/dist/{chunk-BTTFCMKG.js → chunk-74FLKD24.js} +94 -23
  44. package/dist/{chunk-ITTYJZWX.js → chunk-7BUIKDD6.js} +73 -18
  45. package/dist/{chunk-FOKG57CR.js → chunk-7OVVSVEZ.js} +273 -109
  46. package/dist/chunk-AEB7KCHQ.js +287 -0
  47. package/dist/chunk-APCWFOZW.js +28 -0
  48. package/dist/chunk-AWKQIE5I.js +139 -0
  49. package/dist/{chunk-VCDBXW5H.js → chunk-B7N4ASYE.js} +86 -42
  50. package/dist/{chunk-IVNRBPGC.js → chunk-C4GTDLRC.js} +104 -20
  51. package/dist/{chunk-4ZAHCY44.js → chunk-C6APNDVA.js} +12 -5
  52. package/dist/{chunk-4SZYY6AN.js → chunk-CMTVNF3D.js} +18 -13
  53. package/dist/{chunk-WVKKJA6U.js → chunk-CPTOADB2.js} +151 -96
  54. package/dist/chunk-D5N5QWI7.js +1325 -0
  55. package/dist/{chunk-IIQTAY3J.js → chunk-DN7MNQIP.js} +113 -29
  56. package/dist/{chunk-47FWHGUN.js → chunk-DVGBZ3TX.js} +84 -23
  57. package/dist/chunk-DW3L54DQ.js +305 -0
  58. package/dist/{chunk-3ARE4TES.js → chunk-E2E3I5W2.js} +69 -18
  59. package/dist/{chunk-DHWADYZX.js → chunk-EDCBJV7J.js} +41 -28
  60. package/dist/{chunk-WSW6ZFAQ.js → chunk-ENP3BMZU.js} +4 -4
  61. package/dist/{chunk-OOPPQH27.js → chunk-EVOIGUBI.js} +43 -19
  62. package/dist/{chunk-VEAYTRPX.js → chunk-EY4DD67D.js} +165 -97
  63. package/dist/{chunk-223Q2T2Q.js → chunk-F3H33DQX.js} +132 -61
  64. package/dist/{chunk-CYRBHQQZ.js → chunk-F5B3UINI.js} +68 -35
  65. package/dist/{chunk-6X6PQ443.js → chunk-FAJI7BSC.js} +20 -9
  66. package/dist/{chunk-MOUJOP55.js → chunk-FUMHAAF3.js} +96 -29
  67. package/dist/{chunk-6HT2LP62.js → chunk-FV6HMP7W.js} +192 -73
  68. package/dist/{chunk-S7F6XLTK.js → chunk-FYWNRX4F.js} +76 -47
  69. package/dist/{chunk-YG3ZJHGU.js → chunk-FZGAAOKS.js} +30 -8
  70. package/dist/{chunk-YDGVJETP.js → chunk-G3AFC24V.js} +1 -1
  71. package/dist/{chunk-EJBDRVIH.js → chunk-G6UESEVN.js} +15 -8
  72. package/dist/chunk-GDKVKNR2.js +339 -0
  73. package/dist/chunk-GEIGMWNF.js +10 -0
  74. package/dist/{chunk-JUAMLEHX.js → chunk-H7DWSL4O.js} +24 -12
  75. package/dist/chunk-HJFFOOJ4.js +1 -0
  76. package/dist/{chunk-RW6ZL2FQ.js → chunk-HJLPZA4X.js} +106 -21
  77. package/dist/chunk-HYEOQWT7.js +647 -0
  78. package/dist/chunk-I2KLQ2HA.js +19 -0
  79. package/dist/{chunk-CJ5EOYZE.js → chunk-I4FHVKEC.js} +11 -5
  80. package/dist/{chunk-JNH2TYIN.js → chunk-IDM7JJMO.js} +19 -5
  81. package/dist/{chunk-O4AEHWII.js → chunk-IPUNJMAQ.js} +141 -49
  82. package/dist/{chunk-J7Q7VCVC.js → chunk-IT6FUXXG.js} +13 -6
  83. package/dist/{chunk-QJJ6MADV.js → chunk-IVKMZ7BB.js} +80 -28
  84. package/dist/{chunk-Z7H7VSFZ.js → chunk-IXKWIFWZ.js} +17 -6
  85. package/dist/chunk-J64KGCGX.js +55 -0
  86. package/dist/chunk-JBMLWFSJ.js +270 -0
  87. package/dist/{chunk-4BXMXBJO.js → chunk-JJLPBRVZ.js} +22 -11
  88. package/dist/chunk-JLC6PM5S.js +406 -0
  89. package/dist/chunk-JUYWSSKW.js +335 -0
  90. package/dist/{chunk-7CFF4HXS.js → chunk-JV5YOTOB.js} +49 -11
  91. package/dist/{chunk-LZLHELAG.js → chunk-KFJGFLMW.js} +29 -8
  92. package/dist/{chunk-O7AE6DAF.js → chunk-KQZ3GLHR.js} +18 -8
  93. package/dist/{chunk-N32RGOA5.js → chunk-LKFC4CS7.js} +80 -24
  94. package/dist/{chunk-YC6WORFL.js → chunk-LMPHCVJJ.js} +82 -50
  95. package/dist/{chunk-3WPW4KUN.js → chunk-LQP4KEXZ.js} +45 -13
  96. package/dist/{chunk-TKQYWZ5V.js → chunk-LUMVGO2K.js} +47 -31
  97. package/dist/{chunk-AWJOCGFZ.js → chunk-M656FYNH.js} +25 -13
  98. package/dist/{chunk-35OFI3JG.js → chunk-MKSNFG7H.js} +73 -20
  99. package/dist/{chunk-4GBOGOTV.js → chunk-NBEF4EPJ.js} +16 -6
  100. package/dist/chunk-NNCOFLNE.js +24 -0
  101. package/dist/{chunk-4YQOR7JM.js → chunk-NTQ2F3AU.js} +73 -20
  102. package/dist/{chunk-QCDXZBC5.js → chunk-O5V4TG3V.js} +126 -44
  103. package/dist/{chunk-U7TFM2JA.js → chunk-OJQUBQWA.js} +3 -3
  104. package/dist/{chunk-VQHPQEUH.js → chunk-OWAMM2DK.js} +13 -6
  105. package/dist/chunk-PID3NJB7.js +405 -0
  106. package/dist/{chunk-66SG2H23.js → chunk-PMMTGBBS.js} +27 -17
  107. package/dist/{chunk-RIBDXGUG.js → chunk-PNF3NKB5.js} +49 -16
  108. package/dist/{chunk-JXJB2X6M.js → chunk-Q6NKEPRE.js} +81 -32
  109. package/dist/chunk-QDZGFXQD.js +176 -0
  110. package/dist/{chunk-SYNOJOQO.js → chunk-QEYFDRHR.js} +60 -26
  111. package/dist/{chunk-VBOXAEPI.js → chunk-QHAITQIF.js} +97 -22
  112. package/dist/{chunk-VXDZFJGP.js → chunk-QHTVYA65.js} +230 -76
  113. package/dist/{chunk-TUTI5HOZ.js → chunk-QIKT7LIB.js} +14 -8
  114. package/dist/{chunk-3ENTMPQY.js → chunk-QP3KMOVF.js} +82 -42
  115. package/dist/{chunk-GNNJ4GCC.js → chunk-QPWDDJJ4.js} +62 -148
  116. package/dist/{chunk-QWCMU5B2.js → chunk-QRUMA22E.js} +205 -80
  117. package/dist/{chunk-ZVFE5QGU.js → chunk-QYPE5JX3.js} +50 -10
  118. package/dist/{chunk-PUPM2YGF.js → chunk-ROCUG24E.js} +76 -36
  119. package/dist/{chunk-NQYBUO3K.js → chunk-RU3ZPNL6.js} +333 -142
  120. package/dist/{chunk-TOXAGRDQ.js → chunk-RXSCIO6W.js} +14 -5
  121. package/dist/{chunk-FIF2M24N.js → chunk-SATMR6SG.js} +631 -203
  122. package/dist/{chunk-4YIP3CWS.js → chunk-SHHY5OMK.js} +7 -5
  123. package/dist/chunk-SKWO3SZF.js +2284 -0
  124. package/dist/{chunk-YF4NSSMT.js → chunk-SWS5JQIF.js} +41 -13
  125. package/dist/{chunk-CUMUNPXY.js → chunk-T5LTPKX6.js} +15 -7
  126. package/dist/{chunk-H6NIOQHK.js → chunk-TDMG26JI.js} +26 -6
  127. package/dist/{chunk-UWFLYMAR.js → chunk-TLCIR6RG.js} +267 -126
  128. package/dist/{chunk-SBMNWWBV.js → chunk-TN2ZNJUI.js} +47 -9
  129. package/dist/{chunk-5YNTNN5A.js → chunk-TQVAIKFD.js} +106 -41
  130. package/dist/chunk-TRGFFU6A.js +1456 -0
  131. package/dist/{chunk-2GK6PHGE.js → chunk-TY4MTKQJ.js} +100 -22
  132. package/dist/{chunk-AZRX6SAC.js → chunk-U23FYWME.js} +15 -7
  133. package/dist/{chunk-PZXZJBMP.js → chunk-U5NLHYV6.js} +26 -12
  134. package/dist/chunk-UQEN55EY.js +1 -0
  135. package/dist/chunk-UQGBTPXH.js +218 -0
  136. package/dist/chunk-UXGIW7OK.js +116 -0
  137. package/dist/{chunk-PJXUJYS6.js → chunk-UYGDJWMN.js} +55 -30
  138. package/dist/{chunk-QDYDBCFP.js → chunk-V2OEB75Z.js} +50 -51
  139. package/dist/{chunk-LSS54GLJ.js → chunk-VAOAKWUK.js} +34 -13
  140. package/dist/{chunk-DM5QUKKO.js → chunk-VDPK5CY4.js} +18 -6
  141. package/dist/chunk-W23G6JLF.js +37 -0
  142. package/dist/{chunk-CDRZHT42.js → chunk-W63AJTM7.js} +276 -12
  143. package/dist/{chunk-XXXEFXY5.js → chunk-W74TXYFB.js} +13 -5
  144. package/dist/{chunk-LRJNDEIA.js → chunk-WRDSPUE7.js} +144 -29
  145. package/dist/{chunk-C2NTXVWM.js → chunk-XBZGDDMR.js} +11 -4
  146. package/dist/{chunk-BV3B2HYZ.js → chunk-XIDTBCBA.js} +189 -131
  147. package/dist/{chunk-DSJBXLUG.js → chunk-XN4KG3P4.js} +348 -153
  148. package/dist/chunk-XQXMLMH3.js +211 -0
  149. package/dist/{chunk-HPPW424V.js → chunk-XTORZWRF.js} +19 -8
  150. package/dist/{chunk-P23EQNRQ.js → chunk-YAAHPATV.js} +181 -30
  151. package/dist/{chunk-KMI5ML5I.js → chunk-YXOAPXMU.js} +57 -18
  152. package/dist/{chunk-RJQOOHT2.js → chunk-ZECZOOSB.js} +59 -28
  153. package/dist/{chunk-QKXCPTFS.js → chunk-ZLTO5VQI.js} +121 -31
  154. package/dist/{chunk-BEDBFJND.js → chunk-ZVATDZOM.js} +16 -18
  155. package/dist/coachmark/index.js +6 -3
  156. package/dist/code-block/index.js +5 -3
  157. package/dist/color-field/index.js +6 -4
  158. package/dist/commerce/index.js +19 -16
  159. package/dist/connectivity/index.js +5 -2
  160. package/dist/context-menu/index.js +5 -3
  161. package/dist/copy-button/index.js +4 -2
  162. package/dist/data-grid/index.js +21 -16
  163. package/dist/date-range-picker/index.js +11 -8
  164. package/dist/description-list/index.js +3 -1
  165. package/dist/dialog/index.js +4 -2
  166. package/dist/empty-state/index.js +4 -2
  167. package/dist/error-summary/index.js +4 -2
  168. package/dist/fab/index.js +5 -2
  169. package/dist/file-manager/index.js +28 -0
  170. package/dist/file-upload/index.js +10 -7
  171. package/dist/filter-bar/index.js +9 -6
  172. package/dist/flow-run/index.js +15 -12
  173. package/dist/form/index.js +5 -3
  174. package/dist/gallery/index.js +5 -2
  175. package/dist/hold-to-confirm/index.js +4 -2
  176. package/dist/index.d.ts +9557 -2985
  177. package/dist/index.js +355 -122
  178. package/dist/infinite-list/index.js +4 -2
  179. package/dist/inline-edit/index.js +6 -4
  180. package/dist/input/index.js +5 -3
  181. package/dist/interactions/index.js +2 -1
  182. package/dist/invoice/index.js +13 -9
  183. package/dist/kbd/index.js +5 -1
  184. package/dist/keyboard/index.js +4 -2
  185. package/dist/list-row/index.js +6 -4
  186. package/dist/log-viewer/index.js +4 -2
  187. package/dist/map-view/index.js +5 -3
  188. package/dist/markdown/index.js +9 -6
  189. package/dist/metric/index.js +7 -4
  190. package/dist/money/index.js +9 -3
  191. package/dist/nav-drawer/index.js +4 -2
  192. package/dist/nav-header/index.js +9 -0
  193. package/dist/navigation/index.js +5 -2
  194. package/dist/notification-center/index.js +12 -10
  195. package/dist/number-roll/index.js +5 -2
  196. package/dist/one-handed/index.js +5 -3
  197. package/dist/os-surfaces/index.js +6 -3
  198. package/dist/otp/index.js +7 -4
  199. package/dist/page-header/index.js +1 -0
  200. package/dist/pagination/index.js +6 -0
  201. package/dist/payment-method/index.js +14 -10
  202. package/dist/payment-status/index.js +17 -14
  203. package/dist/permission/index.js +5 -2
  204. package/dist/picker/index.js +11 -6
  205. package/dist/progress/index.js +6 -3
  206. package/dist/pull-to-refresh/index.js +4 -2
  207. package/dist/radio-group/index.js +6 -4
  208. package/dist/rating/index.js +5 -2
  209. package/dist/receivables/index.js +21 -16
  210. package/dist/refund/index.js +18 -14
  211. package/dist/save-status/index.js +5 -3
  212. package/dist/scroll-area/index.js +3 -1
  213. package/dist/search-field/index.js +8 -0
  214. package/dist/segmented-control/index.js +4 -3
  215. package/dist/sheet/index.js +5 -3
  216. package/dist/skeleton/index.js +3 -1
  217. package/dist/slider/index.js +4 -2
  218. package/dist/sortable/index.js +7 -0
  219. package/dist/spinner/index.js +3 -1
  220. package/dist/split-button/index.js +9 -6
  221. package/dist/spotlight/index.js +3 -1
  222. package/dist/stage-timeline/index.js +5 -3
  223. package/dist/status-dot/index.js +4 -2
  224. package/dist/stepper/index.js +7 -4
  225. package/dist/streaming-text/index.js +3 -2
  226. package/dist/survey/index.js +18 -15
  227. package/dist/switch/index.js +5 -3
  228. package/dist/system-state/index.js +7 -4
  229. package/dist/tab-bar/index.js +5 -2
  230. package/dist/tabs/index.js +4 -2
  231. package/dist/tags-input/index.js +10 -0
  232. package/dist/textarea/index.js +6 -4
  233. package/dist/thinking/index.js +3 -1
  234. package/dist/time-field/index.js +12 -0
  235. package/dist/time-range-control/index.js +22 -0
  236. package/dist/timeline/index.js +4 -2
  237. package/dist/toast/index.js +4 -2
  238. package/dist/toolbar/index.js +4 -2
  239. package/dist/tour/index.js +12 -9
  240. package/dist/truncation-notice/index.js +5 -2
  241. package/dist/update-notice/index.js +12 -9
  242. package/dist/video-player/index.js +5 -2
  243. package/dist/viewfinder/index.js +6 -4
  244. package/dist/widget/index.js +7 -4
  245. package/dist/wizard/index.js +7 -4
  246. package/package.json +13 -12
  247. package/dist/chunk-6N33LFQA.js +0 -35
  248. package/dist/chunk-GDKZTW34.js +0 -395
  249. package/dist/chunk-GL7B2DOW.js +0 -134
  250. package/dist/chunk-NKB7BZYK.js +0 -167
  251. package/dist/chunk-OETCUXQP.js +0 -134
  252. package/dist/chunk-OPXFZ4Y5.js +0 -204
  253. package/dist/chunk-Q72LJOVE.js +0 -169
  254. package/dist/chunk-RNGLIHFA.js +0 -191
  255. package/dist/chunk-RQ3HASCC.js +0 -6
  256. package/dist/chunk-RSOJT5YW.js +0 -124
  257. package/dist/chunk-TKVFVF5D.js +0 -95
  258. package/dist/chunk-XOSCY2CW.js +0 -242
  259. package/dist/header/index.js +0 -5
  260. package/dist/search-bar/index.js +0 -5
  261. /package/dist/{chunk-3ECPOSKO.js → chunk-3UG6JUCV.js} +0 -0
  262. /package/dist/{chunk-JRLTGLN4.js → chunk-5WWRTEPS.js} +0 -0
  263. /package/dist/{chunk-RTIKSY6A.js → chunk-5Z5ZYMOJ.js} +0 -0
@@ -1,24 +1,25 @@
1
- import { Stepper } from './chunk-VQHPQEUH.js';
2
- import { DescriptionList } from './chunk-TUTI5HOZ.js';
3
- import { PhaseAnnouncement, ConfidenceBadge, MatchRow, NoteBlock } from './chunk-N32RGOA5.js';
4
- import { Card, CardHeader, CardTitle, CardContent, CardFooter } from './chunk-KMI5ML5I.js';
5
- import { Input } from './chunk-ITTYJZWX.js';
6
- import { Badge } from './chunk-SBMNWWBV.js';
7
- import { PlaceholderFeed } from './chunk-LAECSR4H.js';
8
- import { decorativeProps, GuidanceChip, camInk } from './chunk-RW6ZL2FQ.js';
9
- import { Button } from './chunk-3ARE4TES.js';
10
- import { useReducedMotion } from './chunk-6N33LFQA.js';
11
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { Stepper } from './chunk-OWAMM2DK.js';
2
+ import { DescriptionList } from './chunk-QIKT7LIB.js';
3
+ import { useCaptureResultLabels, PhaseAnnouncement, ConfidenceBadge, MatchRow, NoteBlock } from './chunk-LKFC4CS7.js';
4
+ import { Card, CardHeader, CardTitle, CardContent, CardFooter } from './chunk-YXOAPXMU.js';
5
+ import { Input } from './chunk-7BUIKDD6.js';
6
+ import { Badge } from './chunk-TN2ZNJUI.js';
7
+ import { PlaceholderFeed } from './chunk-5LAAAXFP.js';
8
+ import { decorativeProps, useAnalyzerCopy, GuidanceChip, camInk } from './chunk-HJLPZA4X.js';
9
+ import { Button } from './chunk-E2E3I5W2.js';
10
+ import { useLoamLocale } from './chunk-APCWFOZW.js';
11
+ import { Icon } from './chunk-UXGIW7OK.js';
12
+ import { useReducedMotion, useResolvedMotion, springConfig, motionTiming } from './chunk-J64KGCGX.js';
12
13
  import * as React5 from 'react';
13
14
  import { Animated, View, Text, Pressable, Platform, findNodeHandle, AccessibilityInfo, PanResponder, ScrollView, Easing } from 'react-native';
14
15
  import Svg, { Defs, LinearGradient, Stop, Rect } from 'react-native-svg';
15
16
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
16
- import { STAGE_PRIVACY, profile, pipelineFrom, PIPELINE_FOOTER, RESULT_NOTES, estimateRange, failure, failureBody, FAILURE_OFFER_PREFIX, FAILURE_SECONDARY_LABEL, failurePrimaryLabel, CAPTURED_PILL, resultPrimaryLabel, fieldFlagged, FIELD_FLAG_COPY } from '@btndprojects/loam-analyzer';
17
+ import { localizeProfile, profile, pipelineFrom, estimateRange, failure, failureBody, failurePrimaryLabel, resultPrimaryLabel, fieldFlagged } from '@btndprojects/loam-analyzer';
17
18
  import { jsx, jsxs } from 'react/jsx-runtime';
18
19
  import { money } from '@btndprojects/loam-pay';
19
20
 
20
21
  function ScanSweep({ active = true }) {
21
- const theme = useLoamTheme();
22
+ const theme = useLoamTheme("capture-result");
22
23
  const reduced = useReducedMotion();
23
24
  const { styles } = useStyles(analysisSheet);
24
25
  const [band, setBand] = React5.useState(0);
@@ -42,82 +43,138 @@ function ScanSweep({ active = true }) {
42
43
  if (!active) return null;
43
44
  const onLayout = (e) => setBand(e.nativeEvent.layout.height);
44
45
  const translateY = still ? band : phase.interpolate({ inputRange: [0, 1], outputRange: [-band, band * 4] });
45
- return /* @__PURE__ */ jsx(View, { accessible: false, testID: "loam-scan-sweep", style: styles.sweepRoot, ...decorativeProps(), children: /* @__PURE__ */ jsx(
46
- Animated.View,
46
+ return /* @__PURE__ */ jsx(
47
+ View,
47
48
  {
48
- testID: still ? "loam-scan-sweep-static" : "loam-scan-sweep-band",
49
- onLayout,
50
- style: [styles.sweepBand, { transform: [{ translateY }] }],
51
- children: /* @__PURE__ */ jsxs(Svg, { width: "100%", height: "100%", children: [
52
- /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(LinearGradient, { id: "loam-cam-sweep", x1: "0", y1: "0", x2: "0", y2: "1", children: [
53
- /* @__PURE__ */ jsx(Stop, { offset: "0", stopColor: theme.color.good, stopOpacity: theme.opacity[0] }),
54
- /* @__PURE__ */ jsx(Stop, { offset: "0.5", stopColor: theme.color.good, stopOpacity: theme.opacity[100] }),
55
- /* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: theme.color.good, stopOpacity: theme.opacity[0] })
56
- ] }) }),
57
- /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#loam-cam-sweep)" })
58
- ] })
49
+ accessible: false,
50
+ testID: "loam-scan-sweep",
51
+ style: styles.sweepRoot,
52
+ ...decorativeProps(),
53
+ children: /* @__PURE__ */ jsx(
54
+ Animated.View,
55
+ {
56
+ testID: still ? "loam-scan-sweep-static" : "loam-scan-sweep-band",
57
+ onLayout,
58
+ style: [styles.sweepBand, { transform: [{ translateY }] }],
59
+ children: /* @__PURE__ */ jsxs(Svg, { width: "100%", height: "100%", children: [
60
+ /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(LinearGradient, { id: "loam-cam-sweep", x1: "0", y1: "0", x2: "0", y2: "1", children: [
61
+ /* @__PURE__ */ jsx(Stop, { offset: "0", stopColor: theme.color.good, stopOpacity: theme.opacity[0] }),
62
+ /* @__PURE__ */ jsx(Stop, { offset: "0.5", stopColor: theme.color.good, stopOpacity: theme.opacity[100] }),
63
+ /* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: theme.color.good, stopOpacity: theme.opacity[0] })
64
+ ] }) }),
65
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#loam-cam-sweep)" })
66
+ ] })
67
+ }
68
+ )
59
69
  }
60
- ) });
70
+ );
71
+ }
72
+ function StageBadge({ where, copy }) {
73
+ const words = useAnalyzerCopy(copy);
74
+ const locale = useLoamLocale();
75
+ const privacy = where === "device" ? words.pipeline.device : words.pipeline.server;
76
+ return /* @__PURE__ */ jsx(View, { accessible: false, importantForAccessibility: "no-hide-descendants", ...decorativeProps(), children: /* @__PURE__ */ jsx(Badge, { variant: where === "device" ? "good" : "neutral", size: "sm", children: privacy.toLocaleUpperCase(locale) }) });
61
77
  }
62
- function StageBadge({ where }) {
63
- const privacy = STAGE_PRIVACY[where];
64
- return /* @__PURE__ */ jsx(View, { accessible: false, importantForAccessibility: "no-hide-descendants", ...decorativeProps(), children: /* @__PURE__ */ jsx(Badge, { variant: where === "device" ? "good" : "neutral", size: "sm", children: privacy.badge.toUpperCase() }) });
78
+ function DoneCheck() {
79
+ const theme = useLoamTheme("capture-result");
80
+ const reduced = useReducedMotion();
81
+ const v = React5.useRef(new Animated.Value(0)).current;
82
+ React5.useEffect(() => {
83
+ if (reduced) {
84
+ Animated.timing(v, {
85
+ duration: theme.duration.fast,
86
+ toValue: 1,
87
+ useNativeDriver: true
88
+ }).start();
89
+ return;
90
+ }
91
+ Animated.spring(v, { ...springConfig(theme, "fs"), toValue: 1, useNativeDriver: true }).start();
92
+ }, []);
93
+ return /* @__PURE__ */ jsx(
94
+ Animated.View,
95
+ {
96
+ style: {
97
+ opacity: v,
98
+ transform: reduced ? [] : [{ scale: v.interpolate({ inputRange: [0, 1], outputRange: [0.5, 1] }) }]
99
+ },
100
+ children: /* @__PURE__ */ jsx(Icon, { name: "check-circle", size: theme.icon.sm, color: theme.color.good })
101
+ }
102
+ );
65
103
  }
66
104
  function StageDot({ status }) {
67
- const theme = useLoamTheme();
105
+ const theme = useLoamTheme("capture-result");
68
106
  const { styles } = useStyles(analysisSheet, { status });
69
- if (status === "done") {
70
- return /* @__PURE__ */ jsx(Icon, { name: "check-circle", size: theme.icon.sm, color: theme.color.good });
71
- }
107
+ if (status === "done") return /* @__PURE__ */ jsx(DoneCheck, {});
72
108
  if (status === "failed") {
73
109
  return /* @__PURE__ */ jsx(Icon, { name: "alert-circle", size: theme.icon.sm, color: theme.color.danger });
74
110
  }
75
111
  return /* @__PURE__ */ jsx(View, { accessible: false, style: styles.dot });
76
112
  }
77
- function StageRow({ stage, status = "pending" }) {
113
+ function StageRow({
114
+ stage,
115
+ status = "pending",
116
+ labels,
117
+ copy
118
+ }) {
119
+ const t = useCaptureResultLabels(labels);
120
+ const words = useAnalyzerCopy(copy);
78
121
  const { styles } = useStyles(analysisSheet, { status });
79
122
  return /* @__PURE__ */ jsxs(
80
123
  View,
81
124
  {
82
125
  role: "listitem",
83
126
  accessible: true,
84
- accessibilityLabel: `${stage.label}, ${status}, runs on ${stage.where}`,
127
+ accessibilityLabel: `${stage.label}${t.stageNote(t.stageStatus[status], words.pipeline[stage.where])}`,
85
128
  testID: `loam-stage-${status}`,
86
129
  style: styles.stageRow,
87
130
  children: [
88
131
  /* @__PURE__ */ jsx(StageDot, { status }),
89
132
  /* @__PURE__ */ jsx(Text, { style: styles.stageLabel, children: stage.label }),
90
- /* @__PURE__ */ jsx(StageBadge, { where: stage.where })
133
+ /* @__PURE__ */ jsx(StageBadge, { where: stage.where, copy })
91
134
  ]
92
135
  }
93
136
  );
94
137
  }
95
- function defaultTitle(p) {
96
- return p.id === "car" ? "Reading six angles" : "Analysing";
138
+ function defaultTitle(p, t) {
139
+ return p.id === "car" ? t.readingAngles : t.analysing;
97
140
  }
98
141
  function AnalysisProgress({
99
142
  profile: profileProp,
100
143
  index = 0,
101
144
  title,
102
- cancelLabel = "Cancel",
145
+ cancelLabel,
103
146
  onCancel,
104
- footer = PIPELINE_FOOTER,
105
- announce = true
147
+ footer: footerProp,
148
+ announce = true,
149
+ labels,
150
+ copy
106
151
  }) {
107
152
  const { styles } = useStyles(analysisSheet);
108
- const p = profile(profileProp);
153
+ const t = useCaptureResultLabels(labels);
154
+ const words = useAnalyzerCopy(copy);
155
+ const footer = footerProp === void 0 ? words.pipeline.footer : footerProp;
156
+ const p = React5.useMemo(() => localizeProfile(profile(profileProp), words), [profileProp, words]);
109
157
  const pipeline = pipelineFrom(p, index);
110
- const heading = title ?? defaultTitle(p);
158
+ const heading = title ?? defaultTitle(p, t);
111
159
  const active = pipeline.index >= 0 ? pipeline.stages[pipeline.index] : void 0;
112
- const message = announce ? active ? `${active.stage.label}, runs on ${active.stage.where}` : heading : null;
160
+ const message = announce ? active ? words.pipeline.stageAria(active.stage.label, words.pipeline[active.stage.where]) : heading : null;
113
161
  return /* @__PURE__ */ jsxs(Card, { variant: "elevated", style: styles.card, children: [
114
162
  /* @__PURE__ */ jsx(PhaseAnnouncement, { message }),
115
163
  /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { children: /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles.heading, children: heading }) }) }),
116
164
  /* @__PURE__ */ jsxs(CardContent, { children: [
117
- pipeline.stages.length > 0 ? /* @__PURE__ */ jsx(View, { role: "list", style: styles.stageList, children: pipeline.stages.map((s) => /* @__PURE__ */ jsx(StageRow, { stage: s.stage, status: s.status }, s.stage.label)) }) : /* @__PURE__ */ jsx(Text, { style: styles.noPipeline, children: `${p.label} runs no analysis pipeline \u2014 the capture is kept as it is.` }),
165
+ pipeline.stages.length > 0 ? /* @__PURE__ */ jsx(View, { role: "list", style: styles.stageList, children: pipeline.stages.map((s) => /* @__PURE__ */ jsx(
166
+ StageRow,
167
+ {
168
+ stage: s.stage,
169
+ status: s.status,
170
+ labels,
171
+ copy
172
+ },
173
+ s.stage.label
174
+ )) }) : /* @__PURE__ */ jsx(Text, { style: styles.noPipeline, children: words.pipeline.noPipeline(p.label) }),
118
175
  footer ? /* @__PURE__ */ jsx(Text, { style: styles.footer, children: footer }) : null
119
176
  ] }),
120
- onCancel && pipeline.cancellable ? /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onPress: onCancel, children: cancelLabel }) }) : null
177
+ onCancel && pipeline.cancellable ? /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onPress: onCancel, children: cancelLabel ?? t.cancel }) }) : null
121
178
  ] });
122
179
  }
123
180
  var analysisSheet = createStyleSheet((theme) => ({
@@ -225,8 +282,13 @@ function Body({
225
282
  function SpeciesResult({
226
283
  result,
227
284
  onPickAlternate,
228
- alternatesLabel = "Or possibly"
285
+ alternatesLabel,
286
+ labels,
287
+ copy
229
288
  }) {
289
+ const t = useCaptureResultLabels(labels);
290
+ const words = useAnalyzerCopy(copy);
291
+ const locale = useLoamLocale();
230
292
  const { styles } = useStyles(bodySheet);
231
293
  const { top, alternates, facts } = result;
232
294
  return /* @__PURE__ */ jsxs(Body, { kind: "species", children: [
@@ -238,11 +300,11 @@ function SpeciesResult({
238
300
  top.family ? ` \xB7 ${top.family}` : ""
239
301
  ] })
240
302
  ] }),
241
- /* @__PURE__ */ jsx(ConfidenceBadge, { value: top.confidence, size: "md" })
303
+ /* @__PURE__ */ jsx(ConfidenceBadge, { value: top.confidence, size: "md", labels })
242
304
  ] }),
243
305
  alternates.length > 0 ? /* @__PURE__ */ jsxs(View, { style: styles.group, children: [
244
- /* @__PURE__ */ jsx(Text, { style: styles.overline, children: alternatesLabel.toUpperCase() }),
245
- /* @__PURE__ */ jsx(View, { style: styles.list, children: alternates.map((m) => /* @__PURE__ */ jsx(MatchRow, { match: m, onPick: onPickAlternate }, m.name)) })
306
+ /* @__PURE__ */ jsx(Text, { style: styles.overline, children: (alternatesLabel ?? t.orPossibly).toLocaleUpperCase(locale) }),
307
+ /* @__PURE__ */ jsx(View, { style: styles.list, children: alternates.map((m) => /* @__PURE__ */ jsx(MatchRow, { match: m, onPick: onPickAlternate, labels }, m.name)) })
246
308
  ] }) : null,
247
309
  facts.length > 0 ? /* @__PURE__ */ jsx(
248
310
  DescriptionList,
@@ -253,19 +315,24 @@ function SpeciesResult({
253
315
  items: facts.map(([term, description]) => ({ term, description }))
254
316
  }
255
317
  ) : null,
256
- /* @__PURE__ */ jsx(ResultNote, { children: RESULT_NOTES.species })
318
+ /* @__PURE__ */ jsx(ResultNote, { children: words.result.notes.species })
257
319
  ] });
258
320
  }
259
- var SEVERITY = {
260
- none: { variant: "good", label: "no damage" },
261
- minor: { variant: "info", label: "minor" },
262
- moderate: { variant: "warn", label: "moderate" }
321
+ var SEVERITY_VARIANT = {
322
+ none: "good",
323
+ minor: "info",
324
+ moderate: "warn"
263
325
  };
264
326
  function PanelsResult({
265
327
  result,
266
328
  currency = "HUF",
267
- estimateLabel = "Estimate"
329
+ estimateLabel,
330
+ labels,
331
+ copy
268
332
  }) {
333
+ const t = useCaptureResultLabels(labels);
334
+ const words = useAnalyzerCopy(copy);
335
+ const locale = useLoamLocale();
269
336
  const { styles } = useStyles(bodySheet);
270
337
  const { vehicle, findings } = result;
271
338
  const [low, high] = estimateRange(findings);
@@ -276,7 +343,7 @@ function PanelsResult({
276
343
  /* @__PURE__ */ jsx(Text, { style: styles.mono, children: vehicle.vin })
277
344
  ] }),
278
345
  /* @__PURE__ */ jsxs(View, { testID: "loam-estimate", style: styles.estimate, children: [
279
- /* @__PURE__ */ jsx(Text, { style: styles.overline, children: estimateLabel.toUpperCase() }),
346
+ /* @__PURE__ */ jsx(Text, { style: styles.overline, children: (estimateLabel ?? t.estimate).toLocaleUpperCase(locale) }),
280
347
  /* @__PURE__ */ jsxs(View, { style: styles.estimateRow, children: [
281
348
  /* @__PURE__ */ jsx(Money, { minor: low, currency, emphasis: true }),
282
349
  /* @__PURE__ */ jsx(Text, { style: styles.dash, children: "\u2013" }),
@@ -284,35 +351,37 @@ function PanelsResult({
284
351
  ] })
285
352
  ] }),
286
353
  /* @__PURE__ */ jsx(View, { style: styles.list, children: findings.map((f) => {
287
- const sev = SEVERITY[f.severity];
288
354
  return /* @__PURE__ */ jsxs(View, { style: styles.finding, children: [
289
355
  /* @__PURE__ */ jsxs(View, { style: styles.findingTop, children: [
290
356
  /* @__PURE__ */ jsx(Text, { style: styles.findingPanel, children: f.panel }),
291
- /* @__PURE__ */ jsx(Badge, { variant: sev.variant, children: sev.label })
357
+ /* @__PURE__ */ jsx(Badge, { variant: SEVERITY_VARIANT[f.severity], children: words.result.severity[f.severity] })
292
358
  ] }),
293
359
  /* @__PURE__ */ jsxs(View, { style: styles.findingBottom, children: [
294
360
  /* @__PURE__ */ jsx(Text, { style: styles.findingDamage, children: f.damage }),
295
361
  /* @__PURE__ */ jsxs(View, { style: styles.findingMeta, children: [
296
362
  /* @__PURE__ */ jsx(Money, { minor: f.cost, currency }),
297
- /* @__PURE__ */ jsx(ConfidenceBadge, { value: f.confidence })
363
+ /* @__PURE__ */ jsx(ConfidenceBadge, { value: f.confidence, labels })
298
364
  ] })
299
365
  ] })
300
366
  ] }, f.panel);
301
367
  }) }),
302
- /* @__PURE__ */ jsx(ResultNote, { children: RESULT_NOTES.panels })
368
+ /* @__PURE__ */ jsx(ResultNote, { children: words.result.notes.panels })
303
369
  ] });
304
370
  }
305
371
  function FieldRow({
306
372
  field,
307
- onChange
373
+ onChange,
374
+ labels,
375
+ copy
308
376
  }) {
309
- const theme = useLoamTheme();
377
+ const words = useAnalyzerCopy(copy);
378
+ const theme = useLoamTheme("capture-result");
310
379
  const { styles } = useStyles(bodySheet, { flagged: fieldFlagged(field) });
311
380
  const flagged = fieldFlagged(field);
312
381
  return /* @__PURE__ */ jsxs(View, { style: styles.group, children: [
313
382
  /* @__PURE__ */ jsxs(View, { style: styles.fieldHead, children: [
314
383
  /* @__PURE__ */ jsx(Text, { style: styles.fieldLabel, children: field.key }),
315
- /* @__PURE__ */ jsx(ConfidenceBadge, { value: field.confidence })
384
+ /* @__PURE__ */ jsx(ConfidenceBadge, { value: field.confidence, labels })
316
385
  ] }),
317
386
  /* @__PURE__ */ jsx(View, { style: styles.fieldInput, children: /* @__PURE__ */ jsx(
318
387
  Input,
@@ -320,23 +389,29 @@ function FieldRow({
320
389
  size: "sm",
321
390
  value: field.value,
322
391
  editable: !!onChange,
323
- accessibilityLabel: flagged ? `${field.key}, ${FIELD_FLAG_COPY}` : field.key,
324
- accessibilityHint: flagged ? FIELD_FLAG_COPY : void 0,
392
+ accessibilityLabel: flagged ? `${field.key}, ${words.result.fieldFlag}` : field.key,
393
+ accessibilityHint: flagged ? words.result.fieldFlag : void 0,
325
394
  onChangeText: (next) => onChange?.(field.key, next)
326
395
  }
327
396
  ) }),
328
397
  flagged ? /* @__PURE__ */ jsxs(View, { style: styles.flagChip, children: [
329
398
  /* @__PURE__ */ jsx(Icon, { name: "alert-triangle", size: theme.icon.xs, color: theme.color.warnOnSoft }),
330
- /* @__PURE__ */ jsx(Text, { style: styles.flagText, children: FIELD_FLAG_COPY })
399
+ /* @__PURE__ */ jsx(Text, { style: styles.flagText, children: words.result.fieldFlag })
331
400
  ] }) : null
332
401
  ] });
333
402
  }
334
- function FieldsResult({ result, onFieldChange }) {
403
+ function FieldsResult({
404
+ result,
405
+ onFieldChange,
406
+ labels,
407
+ copy
408
+ }) {
409
+ const words = useAnalyzerCopy(copy);
335
410
  const { styles } = useStyles(bodySheet);
336
411
  return /* @__PURE__ */ jsxs(Body, { kind: "fields", children: [
337
412
  /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles.heading, children: result.doc }),
338
- /* @__PURE__ */ jsx(View, { style: styles.fieldList, children: result.fields.map((f) => /* @__PURE__ */ jsx(FieldRow, { field: f, onChange: onFieldChange }, f.key)) }),
339
- /* @__PURE__ */ jsx(ResultNote, { children: RESULT_NOTES.fields })
413
+ /* @__PURE__ */ jsx(View, { style: styles.fieldList, children: result.fields.map((f) => /* @__PURE__ */ jsx(FieldRow, { field: f, onChange: onFieldChange, labels, copy }, f.key)) }),
414
+ /* @__PURE__ */ jsx(ResultNote, { children: words.result.notes.fields })
340
415
  ] });
341
416
  }
342
417
  function CodeResult({
@@ -344,15 +419,20 @@ function CodeResult({
344
419
  currency = "HUF",
345
420
  quantity = 1,
346
421
  onQuantityChange,
347
- quantityLabel = "Quantity"
422
+ quantityLabel: quantityProp,
423
+ labels,
424
+ copy
348
425
  }) {
426
+ const t = useCaptureResultLabels(labels);
427
+ const words = useAnalyzerCopy(copy);
428
+ const quantityLabel = quantityProp ?? t.quantity;
349
429
  const { styles } = useStyles(bodySheet);
350
430
  const { product, format, value } = result;
351
431
  const mono = [format, value, product?.sku].filter(Boolean).join(" \xB7 ");
352
432
  return /* @__PURE__ */ jsxs(Body, { kind: "code", children: [
353
433
  /* @__PURE__ */ jsxs(View, { style: styles.group, children: [
354
434
  /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles.heading, children: product ? product.name : value }),
355
- /* @__PURE__ */ jsx(Text, { style: styles.subheading, children: product ? product.stock : "No product matched this code." })
435
+ /* @__PURE__ */ jsx(Text, { style: styles.subheading, children: product ? product.stock : t.noProduct })
356
436
  ] }),
357
437
  product ? /* @__PURE__ */ jsx(Money, { minor: product.price, currency, emphasis: true }) : null,
358
438
  onQuantityChange ? /* @__PURE__ */ jsxs(View, { style: styles.quantityRow, children: [
@@ -376,15 +456,16 @@ function CodeResult({
376
456
  )
377
457
  ] }) : null,
378
458
  /* @__PURE__ */ jsx(Text, { style: styles.mono, children: mono }),
379
- /* @__PURE__ */ jsx(ResultNote, { children: RESULT_NOTES.code })
459
+ /* @__PURE__ */ jsx(ResultNote, { children: words.result.notes.code })
380
460
  ] });
381
461
  }
382
- function VerdictResult({ result }) {
462
+ function VerdictResult({ result, labels, copy }) {
463
+ const words = useAnalyzerCopy(copy);
383
464
  const { styles } = useStyles(bodySheet);
384
465
  return /* @__PURE__ */ jsxs(Body, { kind: "verdict", children: [
385
466
  /* @__PURE__ */ jsxs(View, { style: styles.headRow, children: [
386
467
  /* @__PURE__ */ jsx(Text, { accessibilityRole: "header", style: styles.heading, children: result.outcome }),
387
- /* @__PURE__ */ jsx(ConfidenceBadge, { value: result.confidence, size: "md", icon: true })
468
+ /* @__PURE__ */ jsx(ConfidenceBadge, { value: result.confidence, size: "md", icon: true, labels })
388
469
  ] }),
389
470
  /* @__PURE__ */ jsx(
390
471
  DescriptionList,
@@ -395,7 +476,7 @@ function VerdictResult({ result }) {
395
476
  items: result.lines.map(([term, description]) => ({ term, description }))
396
477
  }
397
478
  ),
398
- /* @__PURE__ */ jsx(ResultNote, { children: RESULT_NOTES.verdict })
479
+ /* @__PURE__ */ jsx(ResultNote, { children: words.result.notes.verdict })
399
480
  ] });
400
481
  }
401
482
  var bodySheet = createStyleSheet((theme) => ({
@@ -582,14 +663,22 @@ function FailureCard({
582
663
  onRetake,
583
664
  onManualEntry,
584
665
  onPickAlternate,
585
- alternatesLabel = "The closest we got",
586
- manualLabel = FAILURE_SECONDARY_LABEL,
587
- announce = true
666
+ alternatesLabel: alternatesProp,
667
+ manualLabel: manualProp,
668
+ announce = true,
669
+ labels,
670
+ copy
588
671
  }) {
589
- const theme = useLoamTheme();
672
+ const t = useCaptureResultLabels(labels);
673
+ const words = useAnalyzerCopy(copy);
674
+ const locale = useLoamLocale();
675
+ const alternatesLabel = alternatesProp ?? t.closestWeGot;
676
+ const manualLabel = manualProp ?? words.failure.enterManually;
677
+ const theme = useLoamTheme("capture-result");
590
678
  const { styles } = useStyles(failureSheet);
591
- const resolved = failure(failure$1);
592
- const body = failureBody(resolved.id);
679
+ const base = failure(failure$1);
680
+ const resolved = { ...base, ...words.failures[base.id] };
681
+ const body = failureBody(resolved.id, words);
593
682
  const showAlternates = resolved.id === "low_confidence" && alternates.length > 0;
594
683
  return /* @__PURE__ */ jsxs(Card, { variant: "elevated", style: styles.card, children: [
595
684
  /* @__PURE__ */ jsx(PhaseAnnouncement, { message: announce ? `${resolved.label}. ${body}` : null }),
@@ -601,15 +690,15 @@ function FailureCard({
601
690
  ] })
602
691
  ] }) }),
603
692
  /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs(View, { style: styles.stack, children: [
604
- /* @__PURE__ */ jsx(NoteBlock, { title: FAILURE_OFFER_PREFIX, description: resolved.offer }),
693
+ /* @__PURE__ */ jsx(NoteBlock, { title: words.failure.offerPrefix, description: resolved.offer }),
605
694
  showAlternates ? /* @__PURE__ */ jsxs(View, { style: styles.group, children: [
606
- /* @__PURE__ */ jsx(Text, { style: styles.overline, children: alternatesLabel.toUpperCase() }),
607
- /* @__PURE__ */ jsx(View, { style: styles.list, children: alternates.map((m) => /* @__PURE__ */ jsx(MatchRow, { match: m, onPick: onPickAlternate }, m.name)) })
695
+ /* @__PURE__ */ jsx(Text, { style: styles.overline, children: alternatesLabel.toLocaleUpperCase(locale) }),
696
+ /* @__PURE__ */ jsx(View, { style: styles.list, children: alternates.map((m) => /* @__PURE__ */ jsx(MatchRow, { match: m, onPick: onPickAlternate, labels }, m.name)) })
608
697
  ] }) : null
609
698
  ] }) }),
610
699
  /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsxs(View, { style: styles.actions, children: [
611
700
  /* @__PURE__ */ jsx(View, { style: styles.actionSlot, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "lg", fullWidth: true, onPress: onManualEntry, children: manualLabel }) }),
612
- /* @__PURE__ */ jsx(View, { style: styles.actionSlot, children: /* @__PURE__ */ jsx(Button, { variant: "primary", size: "lg", fullWidth: true, onPress: onRetake, children: failurePrimaryLabel(resolved.id) }) })
701
+ /* @__PURE__ */ jsx(View, { style: styles.actionSlot, children: /* @__PURE__ */ jsx(Button, { variant: "primary", size: "lg", fullWidth: true, onPress: onRetake, children: failurePrimaryLabel(resolved.id, words) }) })
613
702
  ] }) })
614
703
  ] });
615
704
  }
@@ -697,19 +786,24 @@ var SCRIM = {
697
786
  };
698
787
  function CapturePreview({
699
788
  preview,
700
- label = "frozen frame \xB7 placeholder",
789
+ label,
701
790
  scrim = "captured",
702
- pill = CAPTURED_PILL,
791
+ pill: pillProp,
792
+ labels,
793
+ copy,
703
794
  tracking,
704
795
  announce = true,
705
796
  children
706
797
  }) {
707
- const theme = useLoamTheme();
798
+ const theme = useLoamTheme("capture-result");
708
799
  const { styles } = useStyles(reviewSheet);
800
+ const t = useCaptureResultLabels(labels);
801
+ const words = useAnalyzerCopy(copy);
802
+ const pill = pillProp === void 0 ? words.capturedPill : pillProp;
709
803
  const stop = SCRIM[scrim];
710
804
  return /* @__PURE__ */ jsxs(View, { testID: `loam-capture-preview-${scrim}`, style: styles.frozen, children: [
711
805
  /* @__PURE__ */ jsx(PhaseAnnouncement, { message: announce && pill ? pill : null }),
712
- preview ?? /* @__PURE__ */ jsx(PlaceholderFeed, { label, drift: false }),
806
+ preview ?? /* @__PURE__ */ jsx(PlaceholderFeed, { label: label ?? t.frozenFrame, drift: false }),
713
807
  stop ? /* @__PURE__ */ jsx(
714
808
  View,
715
809
  {
@@ -726,12 +820,15 @@ function CapturePreview({
726
820
  }
727
821
  function RetakeBar({
728
822
  analyse = true,
729
- retakeLabel = "Retake",
823
+ retakeLabel: retakeProp,
730
824
  acceptLabel,
825
+ labels,
731
826
  onRetake,
732
827
  onAccept
733
828
  }) {
734
- const theme = useLoamTheme();
829
+ const t = useCaptureResultLabels(labels);
830
+ const retakeLabel = retakeProp ?? t.retake;
831
+ const theme = useLoamTheme("capture-result");
735
832
  const { styles } = useStyles(reviewSheet);
736
833
  return /* @__PURE__ */ jsxs(View, { testID: "loam-retake-bar", style: styles.retakeBar, children: [
737
834
  /* @__PURE__ */ jsx(
@@ -744,7 +841,7 @@ function RetakeBar({
744
841
  children: /* @__PURE__ */ jsx(Text, { style: [styles.glassActionLabel, { color: camInk(theme) }], children: retakeLabel })
745
842
  }
746
843
  ),
747
- /* @__PURE__ */ jsx(View, { style: styles.acceptSlot, children: /* @__PURE__ */ jsx(Button, { variant: "primary", size: "lg", fullWidth: true, onPress: onAccept, children: acceptLabel ?? (analyse ? "Analyse" : "Use photo") }) })
844
+ /* @__PURE__ */ jsx(View, { style: styles.acceptSlot, children: /* @__PURE__ */ jsx(Button, { variant: "primary", size: "lg", fullWidth: true, onPress: onAccept, children: acceptLabel ?? (analyse ? t.analyse : t.usePhoto) }) })
748
845
  ] });
749
846
  }
750
847
  var FROZEN_PHASES = [
@@ -821,43 +918,71 @@ function ResultCard({
821
918
  quantity = 1,
822
919
  onFieldChange,
823
920
  onPickAlternate,
824
- onQuantityChange
921
+ onQuantityChange,
922
+ labels,
923
+ copy
825
924
  }) {
826
925
  const stamp = typeof profileProp === "string" ? profileProp : profileProp ? profileProp.id : void 0;
827
926
  return /* @__PURE__ */ jsxs(View, { testID: stamp ? `loam-result-profile-${stamp}` : void 0, children: [
828
- result.kind === "species" ? /* @__PURE__ */ jsx(SpeciesResult, { result, onPickAlternate }) : null,
829
- result.kind === "panels" ? /* @__PURE__ */ jsx(PanelsResult, { result, currency }) : null,
830
- result.kind === "fields" ? /* @__PURE__ */ jsx(FieldsResult, { result, onFieldChange }) : null,
927
+ result.kind === "species" ? /* @__PURE__ */ jsx(
928
+ SpeciesResult,
929
+ {
930
+ result,
931
+ onPickAlternate,
932
+ labels,
933
+ copy
934
+ }
935
+ ) : null,
936
+ result.kind === "panels" ? /* @__PURE__ */ jsx(PanelsResult, { result, currency, labels, copy }) : null,
937
+ result.kind === "fields" ? /* @__PURE__ */ jsx(FieldsResult, { result, onFieldChange, labels, copy }) : null,
831
938
  result.kind === "code" ? /* @__PURE__ */ jsx(
832
939
  CodeResult,
833
940
  {
834
941
  result,
835
942
  currency,
836
943
  quantity,
837
- onQuantityChange
944
+ onQuantityChange,
945
+ labels,
946
+ copy
838
947
  }
839
948
  ) : null,
840
- result.kind === "verdict" ? /* @__PURE__ */ jsx(VerdictResult, { result }) : null
949
+ result.kind === "verdict" ? /* @__PURE__ */ jsx(VerdictResult, { result, labels, copy }) : null
841
950
  ] });
842
951
  }
843
952
  function ResultSheet({
844
- title = "Result",
845
- primaryLabel = resultPrimaryLabel("plant"),
846
- scanAnotherLabel = "Scan another",
953
+ title: titleProp,
954
+ primaryLabel: primaryProp,
955
+ scanAnotherLabel: scanProp,
956
+ labels,
957
+ copy,
847
958
  onScanAnother,
848
959
  onKeep,
849
960
  onDismiss,
850
961
  autoFocus = true,
851
962
  maxHeight = "82%",
852
963
  dismissRatio = 0.3,
853
- grabberLabel = "Dismiss result",
964
+ grabberLabel: grabberProp,
854
965
  children
855
966
  }) {
856
- const theme = useLoamTheme();
967
+ const t = useCaptureResultLabels(labels);
968
+ const words = useAnalyzerCopy(copy);
969
+ const title = titleProp ?? t.result;
970
+ const primaryLabel = primaryProp ?? resultPrimaryLabel("plant", 0, words);
971
+ const scanAnotherLabel = scanProp ?? t.scanAnother;
972
+ const grabberLabel = grabberProp ?? t.dismissResult;
973
+ const theme = useLoamTheme("capture-result");
857
974
  const { styles } = useStyles(sheetSheet);
858
975
  const panel = React5.useRef(null);
859
976
  const height = React5.useRef(0);
860
977
  const offset = React5.useRef(new Animated.Value(0)).current;
978
+ const level = useResolvedMotion(void 0, "capture-result");
979
+ const enter = React5.useRef(new Animated.Value(0)).current;
980
+ const [sheetH, setSheetH] = React5.useState(600);
981
+ const entered = React5.useRef(false);
982
+ const themeRef = React5.useRef(theme);
983
+ themeRef.current = theme;
984
+ const levelRef = React5.useRef(level);
985
+ levelRef.current = level;
861
986
  const dismiss = React5.useRef(onDismiss);
862
987
  dismiss.current = onDismiss;
863
988
  const ratio = React5.useRef(dismissRatio);
@@ -880,10 +1005,19 @@ function ResultSheet({
880
1005
  offset.setValue(Math.max(0, g.dy));
881
1006
  },
882
1007
  onPanResponderRelease: (_e, g) => {
883
- offset.setValue(0);
884
- if (!dismiss.current) return;
885
- if (height.current > 0 && Math.max(0, g.dy) > height.current * ratio.current) {
1008
+ if (dismiss.current && height.current > 0 && Math.max(0, g.dy) > height.current * ratio.current) {
1009
+ offset.setValue(0);
886
1010
  dismiss.current();
1011
+ return;
1012
+ }
1013
+ if (levelRef.current === "full") {
1014
+ Animated.spring(offset, {
1015
+ ...springConfig(themeRef.current, "ds", { velocity: g.vy, thrown: true }),
1016
+ toValue: 0,
1017
+ useNativeDriver: true
1018
+ }).start();
1019
+ } else {
1020
+ offset.setValue(0);
887
1021
  }
888
1022
  },
889
1023
  onPanResponderTerminate: () => offset.setValue(0)
@@ -899,8 +1033,38 @@ function ResultSheet({
899
1033
  testID: "loam-result-sheet",
900
1034
  onLayout: (e) => {
901
1035
  height.current = e.nativeEvent.layout.height;
1036
+ if (entered.current) return;
1037
+ entered.current = true;
1038
+ setSheetH(height.current);
1039
+ if (level === "none") enter.setValue(1);
1040
+ else if (level === "reduced")
1041
+ Animated.timing(enter, {
1042
+ ...motionTiming(level),
1043
+ toValue: 1,
1044
+ useNativeDriver: true
1045
+ }).start();
1046
+ else
1047
+ Animated.spring(enter, {
1048
+ ...springConfig(theme, "ds"),
1049
+ toValue: 1,
1050
+ useNativeDriver: true
1051
+ }).start();
902
1052
  },
903
- style: [styles.sheet, { maxHeight, transform: [{ translateY: offset }] }],
1053
+ style: [
1054
+ styles.sheet,
1055
+ {
1056
+ maxHeight,
1057
+ opacity: level === "full" ? 1 : enter,
1058
+ transform: [
1059
+ { translateY: offset },
1060
+ ...level === "full" ? [
1061
+ {
1062
+ translateY: enter.interpolate({ inputRange: [0, 1], outputRange: [sheetH, 0] })
1063
+ }
1064
+ ] : []
1065
+ ]
1066
+ }
1067
+ ],
904
1068
  children: [
905
1069
  onDismiss ? /* @__PURE__ */ jsx(
906
1070
  Pressable,