@btndprojects/loam-ui-native 0.2.1 → 0.3.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 (365) hide show
  1. package/dist/accordion/index.js +4 -2
  2. package/dist/adaptive/index.js +12 -2
  3. package/dist/address-block/index.js +23 -0
  4. package/dist/alert/index.js +5 -2
  5. package/dist/analyzer/index.js +13 -5
  6. package/dist/announcement/index.js +15 -5
  7. package/dist/appearance-picker/index.js +15 -0
  8. package/dist/audio-player/index.js +26 -2
  9. package/dist/avatar/index.js +2 -2
  10. package/dist/avatar-group/index.js +5 -3
  11. package/dist/badge/index.js +6 -3
  12. package/dist/banner/index.js +3 -2
  13. package/dist/board/index.js +13 -6
  14. package/dist/button/index.js +6 -3
  15. package/dist/camera-permission/index.js +19 -11
  16. package/dist/capture-result/index.js +26 -16
  17. package/dist/card/index.js +7 -3
  18. package/dist/card-form/index.js +15 -9
  19. package/dist/carousel/index.js +3 -1
  20. package/dist/chart/index.js +15 -5
  21. package/dist/charts/index.js +18 -5
  22. package/dist/chat/index.js +35 -10
  23. package/dist/checkbox/index.js +6 -4
  24. package/dist/checklist/index.js +16 -7
  25. package/dist/checkout/index.js +25 -12
  26. package/dist/chip/index.js +7 -4
  27. package/dist/chunk-2BZD3NAP.js +1110 -0
  28. package/dist/chunk-2YKVID2V.js +35 -0
  29. package/dist/{chunk-H7DWSL4O.js → chunk-36DA3IPO.js} +115 -27
  30. package/dist/chunk-3A56MIAN.js +599 -0
  31. package/dist/{chunk-AEB7KCHQ.js → chunk-3SCKCWF5.js} +39 -28
  32. package/dist/chunk-3TZNDHKO.js +187 -0
  33. package/dist/chunk-43K3BLXV.js +9 -0
  34. package/dist/chunk-46ZJIQ2Z.js +208 -0
  35. package/dist/{chunk-PMMTGBBS.js → chunk-4CZMQDQL.js} +75 -22
  36. package/dist/chunk-4QCR3K2J.js +1 -0
  37. package/dist/{chunk-E2E3I5W2.js → chunk-5DTKORLI.js} +54 -45
  38. package/dist/{chunk-5VFZRGVD.js → chunk-5J4WFXFA.js} +32 -15
  39. package/dist/{chunk-JBMLWFSJ.js → chunk-5KJ7TEQ6.js} +83 -48
  40. package/dist/chunk-5NU33TXK.js +529 -0
  41. package/dist/chunk-6KSUS7DF.js +690 -0
  42. package/dist/{chunk-3WEZCGHX.js → chunk-6RV6UW2J.js} +140 -56
  43. package/dist/chunk-6RZM7RP2.js +520 -0
  44. package/dist/{chunk-JJLPBRVZ.js → chunk-75BDCC7K.js} +2 -0
  45. package/dist/{chunk-U5NLHYV6.js → chunk-7CGJBQUA.js} +333 -22
  46. package/dist/{chunk-I4FHVKEC.js → chunk-7IVF6JLJ.js} +16 -5
  47. package/dist/chunk-7IWCGXYA.js +143 -0
  48. package/dist/chunk-7LM4ASFH.js +172 -0
  49. package/dist/chunk-7MCEJFWV.js +341 -0
  50. package/dist/{chunk-2SY63FCH.js → chunk-7NGMUVNU.js} +66 -30
  51. package/dist/chunk-7PBSIXT7.js +355 -0
  52. package/dist/chunk-7QOYGENL.js +443 -0
  53. package/dist/{chunk-TDMG26JI.js → chunk-A7SWYDE5.js} +40 -9
  54. package/dist/chunk-ADHPJALR.js +3051 -0
  55. package/dist/{chunk-ZLTO5VQI.js → chunk-ALJYZLNQ.js} +131 -61
  56. package/dist/{chunk-GDKVKNR2.js → chunk-AQ5FIG74.js} +110 -30
  57. package/dist/chunk-B2MMZZQB.js +426 -0
  58. package/dist/{chunk-QYPE5JX3.js → chunk-B7JZ3N5G.js} +142 -105
  59. package/dist/{chunk-QHTVYA65.js → chunk-BL37SW6G.js} +388 -102
  60. package/dist/chunk-BTRMA7GC.js +21 -0
  61. package/dist/{chunk-FUMHAAF3.js → chunk-C7IUWIUZ.js} +243 -92
  62. package/dist/chunk-CA3DUVYD.js +10 -0
  63. package/dist/{chunk-FYWNRX4F.js → chunk-CBCJSO2B.js} +143 -13
  64. package/dist/chunk-CHPX4MFI.js +239 -0
  65. package/dist/chunk-CLGAMIOT.js +648 -0
  66. package/dist/chunk-CUE7VML6.js +1141 -0
  67. package/dist/{chunk-D5N5QWI7.js → chunk-CVU6S2E5.js} +497 -235
  68. package/dist/{chunk-U23FYWME.js → chunk-CXPQMA6Z.js} +101 -34
  69. package/dist/{chunk-36EC2T6P.js → chunk-D2LN4I7I.js} +1 -1
  70. package/dist/{chunk-TLCIR6RG.js → chunk-D34LNBO5.js} +411 -155
  71. package/dist/{chunk-FV6HMP7W.js → chunk-D4BCQICM.js} +207 -65
  72. package/dist/chunk-EABKIIA4.js +1 -0
  73. package/dist/chunk-EICSYRAG.js +341 -0
  74. package/dist/chunk-EMWAJMAS.js +83 -0
  75. package/dist/chunk-EOLZWRV6.js +149 -0
  76. package/dist/chunk-EOQVTGB6.js +350 -0
  77. package/dist/{chunk-ZVATDZOM.js → chunk-ESGUHNB2.js} +106 -28
  78. package/dist/{chunk-46MMSDGL.js → chunk-F2KNBPKY.js} +104 -73
  79. package/dist/{chunk-KQZ3GLHR.js → chunk-G7H3NX3G.js} +40 -17
  80. package/dist/{chunk-3QMEOFW5.js → chunk-GM7YIPB7.js} +421 -207
  81. package/dist/{chunk-QHAITQIF.js → chunk-GVQQG435.js} +256 -86
  82. package/dist/chunk-HE43OMEL.js +1056 -0
  83. package/dist/{chunk-XIDTBCBA.js → chunk-HHOMFQ7R.js} +1049 -207
  84. package/dist/chunk-HNAKS4Z3.js +207 -0
  85. package/dist/chunk-HP6ST2OW.js +352 -0
  86. package/dist/chunk-HW3OWDTU.js +1 -0
  87. package/dist/{chunk-QP3KMOVF.js → chunk-HZDB44K4.js} +24 -14
  88. package/dist/chunk-I6CUP2LW.js +1155 -0
  89. package/dist/chunk-ICV4Y2WY.js +27 -0
  90. package/dist/chunk-IHSIENOE.js +3950 -0
  91. package/dist/{chunk-T5LTPKX6.js → chunk-IMMALLRU.js} +53 -25
  92. package/dist/{chunk-C4GTDLRC.js → chunk-JA6TK7H2.js} +154 -67
  93. package/dist/{chunk-EVOIGUBI.js → chunk-JAVZ5JPV.js} +43 -13
  94. package/dist/{chunk-CPTOADB2.js → chunk-JCMTP3E4.js} +527 -201
  95. package/dist/{chunk-OJQUBQWA.js → chunk-JCXFFK64.js} +73 -16
  96. package/dist/{chunk-V2OEB75Z.js → chunk-JWCVBFDU.js} +75 -35
  97. package/dist/chunk-JXRTD5RI.js +414 -0
  98. package/dist/chunk-JYIUZUIQ.js +1567 -0
  99. package/dist/chunk-K3TK3GIV.js +219 -0
  100. package/dist/chunk-KEVZIHM2.js +1511 -0
  101. package/dist/{chunk-VAOAKWUK.js → chunk-KHZDNQQD.js} +42 -8
  102. package/dist/chunk-KL4GDV4V.js +131 -0
  103. package/dist/{chunk-Q6NKEPRE.js → chunk-KNILMM4H.js} +73 -28
  104. package/dist/chunk-KRBUZV45.js +25 -0
  105. package/dist/{chunk-7BUIKDD6.js → chunk-KXLDK6HB.js} +91 -30
  106. package/dist/chunk-KZ3X7TSL.js +196 -0
  107. package/dist/{chunk-5UTRIXQ6.js → chunk-L2WMOA2V.js} +187 -43
  108. package/dist/chunk-L4D5LHCH.js +109 -0
  109. package/dist/{chunk-W63AJTM7.js → chunk-LAUJPLDB.js} +236 -71
  110. package/dist/{chunk-TN2ZNJUI.js → chunk-LGNTP5XA.js} +47 -13
  111. package/dist/chunk-LUZFCCSD.js +271 -0
  112. package/dist/{chunk-XTORZWRF.js → chunk-LXJCP4PL.js} +111 -30
  113. package/dist/chunk-MCOZJWPU.js +731 -0
  114. package/dist/{chunk-SATMR6SG.js → chunk-MG4SKWLL.js} +780 -142
  115. package/dist/{chunk-JUYWSSKW.js → chunk-MPEPTSER.js} +95 -16
  116. package/dist/chunk-MWPJ4YGP.js +1 -0
  117. package/dist/{chunk-LUMVGO2K.js → chunk-N7AX4OA4.js} +80 -29
  118. package/dist/chunk-NHSLM6SE.js +523 -0
  119. package/dist/{chunk-IT6FUXXG.js → chunk-NNJLVA7M.js} +43 -11
  120. package/dist/{chunk-TQVAIKFD.js → chunk-NZG75DGA.js} +102 -62
  121. package/dist/chunk-O76QXRBV.js +431 -0
  122. package/dist/chunk-OANH27AK.js +223 -0
  123. package/dist/chunk-OCHPK5YV.js +609 -0
  124. package/dist/chunk-OMHVEVX4.js +436 -0
  125. package/dist/{chunk-SWS5JQIF.js → chunk-ONKQUJWD.js} +187 -60
  126. package/dist/chunk-OVTK7A6T.js +615 -0
  127. package/dist/{chunk-UXGIW7OK.js → chunk-PCEFCOLN.js} +5 -1
  128. package/dist/{chunk-QIKT7LIB.js → chunk-PFLNFIVB.js} +91 -23
  129. package/dist/chunk-PHSZY37H.js +300 -0
  130. package/dist/chunk-PJLTKDVY.js +18 -0
  131. package/dist/{chunk-SHHY5OMK.js → chunk-PK7BN3MI.js} +83 -15
  132. package/dist/{chunk-YXOAPXMU.js → chunk-PWFRDRGS.js} +101 -14
  133. package/dist/{chunk-TY4MTKQJ.js → chunk-PYPMD46W.js} +332 -66
  134. package/dist/chunk-Q6CCHDI7.js +331 -0
  135. package/dist/chunk-QFA5WS2A.js +750 -0
  136. package/dist/chunk-QJMMM4RC.js +124 -0
  137. package/dist/chunk-QYWEVAM6.js +407 -0
  138. package/dist/chunk-R5T4VZ7Z.js +126 -0
  139. package/dist/chunk-R77HFLZD.js +1 -0
  140. package/dist/{chunk-LMPHCVJJ.js → chunk-RAESDNU5.js} +162 -68
  141. package/dist/chunk-RBYQUXNL.js +1 -0
  142. package/dist/chunk-RCM3DT5E.js +1 -0
  143. package/dist/chunk-RGNY56L7.js +282 -0
  144. package/dist/chunk-RIK6UX2K.js +344 -0
  145. package/dist/{chunk-5LAAAXFP.js → chunk-RJA3RXO3.js} +63 -54
  146. package/dist/chunk-RJYRJ3LD.js +1 -0
  147. package/dist/chunk-RMA3NOY4.js +599 -0
  148. package/dist/{chunk-VDPK5CY4.js → chunk-RSWKKAHK.js} +143 -61
  149. package/dist/{chunk-B7N4ASYE.js → chunk-RVOIIX3V.js} +17 -45
  150. package/dist/chunk-SA2RRBGT.js +1077 -0
  151. package/dist/{chunk-7OVVSVEZ.js → chunk-SG3J4R45.js} +440 -169
  152. package/dist/chunk-SPUK7JD4.js +238 -0
  153. package/dist/chunk-SWXV2K5N.js +434 -0
  154. package/dist/chunk-SYJEPXP6.js +1303 -0
  155. package/dist/{chunk-LKFC4CS7.js → chunk-SZLI34TA.js} +18 -9
  156. package/dist/{chunk-NBEF4EPJ.js → chunk-T77WJA74.js} +131 -16
  157. package/dist/chunk-TDWWVJA4.js +630 -0
  158. package/dist/chunk-TFHI5XDR.js +610 -0
  159. package/dist/chunk-TH4PW2WU.js +17 -0
  160. package/dist/chunk-TTQ24HQX.js +12 -0
  161. package/dist/chunk-TUACVJNG.js +12 -0
  162. package/dist/{chunk-F5B3UINI.js → chunk-TUL5RUIA.js} +171 -62
  163. package/dist/{chunk-C6APNDVA.js → chunk-TYOSA7JG.js} +63 -34
  164. package/dist/chunk-TYQTMMEV.js +1 -0
  165. package/dist/{chunk-DW3L54DQ.js → chunk-TZO6YDS7.js} +53 -12
  166. package/dist/{chunk-67IZZ2MJ.js → chunk-U3ETF22F.js} +75 -30
  167. package/dist/{chunk-EDCBJV7J.js → chunk-U6BYHD2N.js} +87 -31
  168. package/dist/{chunk-ENP3BMZU.js → chunk-UF6EJXPQ.js} +16 -1
  169. package/dist/{chunk-IPUNJMAQ.js → chunk-UNNQIPGK.js} +304 -68
  170. package/dist/chunk-UQVO6AJV.js +171 -0
  171. package/dist/{chunk-FZGAAOKS.js → chunk-VFDQAAIW.js} +138 -32
  172. package/dist/chunk-VIUE3VQT.js +1 -0
  173. package/dist/{chunk-5RENVKBQ.js → chunk-VJLSSSGC.js} +126 -30
  174. package/dist/chunk-VLMT6KYT.js +350 -0
  175. package/dist/chunk-VMHGBUGS.js +35 -0
  176. package/dist/{chunk-4IZXHVFJ.js → chunk-VQKPBYW6.js} +228 -172
  177. package/dist/{chunk-G6UESEVN.js → chunk-VSSTWLC5.js} +49 -11
  178. package/dist/{chunk-TRGFFU6A.js → chunk-VZYYZRPN.js} +866 -330
  179. package/dist/{chunk-JLC6PM5S.js → chunk-WAIJCD2V.js} +128 -54
  180. package/dist/chunk-WFMQ3WKM.js +378 -0
  181. package/dist/chunk-WJ2KDRMY.js +66 -0
  182. package/dist/chunk-WKFZJO54.js +437 -0
  183. package/dist/{chunk-QEYFDRHR.js → chunk-WVVD3XOV.js} +146 -84
  184. package/dist/chunk-XAIWMSLB.js +1 -0
  185. package/dist/chunk-XBXUBBJZ.js +98 -0
  186. package/dist/chunk-XCU7MYBJ.js +1 -0
  187. package/dist/chunk-XHE4PGCI.js +717 -0
  188. package/dist/chunk-XRSJ32M3.js +331 -0
  189. package/dist/chunk-XTCVOEAW.js +1 -0
  190. package/dist/chunk-XWGXVQF6.js +58 -0
  191. package/dist/{chunk-MKSNFG7H.js → chunk-Y3XKKO5K.js} +191 -109
  192. package/dist/chunk-Y4QNMBLO.js +533 -0
  193. package/dist/chunk-Y5H4CTKO.js +1 -0
  194. package/dist/chunk-YBQIN75A.js +403 -0
  195. package/dist/{chunk-PNF3NKB5.js → chunk-YJ5PXOX3.js} +28 -11
  196. package/dist/{chunk-M656FYNH.js → chunk-YLRSRUPS.js} +63 -49
  197. package/dist/chunk-YM6MPJ4A.js +1 -0
  198. package/dist/chunk-YV7KZENV.js +200 -0
  199. package/dist/chunk-Z7I4ZSO6.js +316 -0
  200. package/dist/{chunk-EY4DD67D.js → chunk-ZIRMWD2B.js} +199 -126
  201. package/dist/chunk-ZPMG3FWU.js +75 -0
  202. package/dist/{chunk-QRUMA22E.js → chunk-ZTXMK2G7.js} +92 -43
  203. package/dist/{chunk-2OLKPG4E.js → chunk-ZVJCWXAL.js} +189 -87
  204. package/dist/{chunk-YAAHPATV.js → chunk-ZYQ23DPT.js} +49 -34
  205. package/dist/coachmark/index.js +7 -3
  206. package/dist/code-block/index.js +4 -3
  207. package/dist/color-field/index.js +12 -4
  208. package/dist/color-picker/index.js +23 -0
  209. package/dist/commerce/index.js +27 -16
  210. package/dist/confirm/index.js +31 -0
  211. package/dist/connection-card/index.js +34 -0
  212. package/dist/connectivity/index.js +3 -2
  213. package/dist/context-menu/index.js +10 -2
  214. package/dist/copy-button/index.js +3 -2
  215. package/dist/data-grid/index.js +30 -17
  216. package/dist/date-range-picker/index.js +19 -9
  217. package/dist/description-list/index.js +4 -1
  218. package/dist/device-frame/index.js +30 -0
  219. package/dist/dialog/index.js +8 -2
  220. package/dist/divider/index.js +2 -0
  221. package/dist/empty-state/index.js +13 -2
  222. package/dist/error-summary/index.js +7 -2
  223. package/dist/fab/index.js +4 -2
  224. package/dist/file-manager/index.js +33 -17
  225. package/dist/file-upload/index.js +12 -6
  226. package/dist/filter-bar/index.js +10 -6
  227. package/dist/flow-run/index.js +19 -12
  228. package/dist/form/index.js +30 -3
  229. package/dist/gallery/index.js +5 -2
  230. package/dist/hold-to-confirm/index.js +4 -2
  231. package/dist/hover-card/index.js +18 -0
  232. package/dist/icon-tile/index.js +10 -0
  233. package/dist/image/index.js +9 -0
  234. package/dist/index.d.ts +29826 -17941
  235. package/dist/index.js +197 -141
  236. package/dist/infinite-list/index.js +4 -2
  237. package/dist/inline-edit/index.js +5 -4
  238. package/dist/input/index.js +4 -3
  239. package/dist/interactions/index.js +4 -1
  240. package/dist/invoice/index.js +18 -9
  241. package/dist/job-row/index.js +22 -0
  242. package/dist/json-inspector/index.js +20 -0
  243. package/dist/kbd/index.js +2 -2
  244. package/dist/keyboard/index.js +7 -2
  245. package/dist/level-meter/index.js +9 -0
  246. package/dist/list-row/index.js +11 -3
  247. package/dist/log-viewer/index.js +9 -2
  248. package/dist/map-view/index.js +13 -2
  249. package/dist/markdown/index.js +8 -5
  250. package/dist/metric/index.js +6 -3
  251. package/dist/metric-strip/index.js +12 -0
  252. package/dist/money/index.js +11 -4
  253. package/dist/nav-drawer/index.js +6 -2
  254. package/dist/nav-header/index.js +10 -4
  255. package/dist/navigation/index.js +29 -2
  256. package/dist/notification-center/index.js +24 -10
  257. package/dist/number-roll/index.js +3 -1
  258. package/dist/onboarding-pager/index.js +22 -0
  259. package/dist/one-handed/index.js +2 -2
  260. package/dist/os-surfaces/index.js +6 -3
  261. package/dist/otp/index.js +5 -4
  262. package/dist/page-header/index.js +2 -1
  263. package/dist/pagination/index.js +4 -2
  264. package/dist/payment-method/index.js +17 -11
  265. package/dist/payment-status/index.js +22 -14
  266. package/dist/permission/index.js +18 -2
  267. package/dist/picker/index.js +17 -6
  268. package/dist/progress/index.js +7 -2
  269. package/dist/provenance/index.js +16 -0
  270. package/dist/pull-to-refresh/index.js +2 -2
  271. package/dist/qr-code/index.js +16 -0
  272. package/dist/query-builder/index.js +30 -0
  273. package/dist/radio-group/index.js +6 -4
  274. package/dist/rating/index.js +7 -2
  275. package/dist/receivables/index.js +31 -18
  276. package/dist/recording-indicator/index.js +21 -0
  277. package/dist/refund/index.js +24 -15
  278. package/dist/repeatable-rows/index.js +19 -0
  279. package/dist/save-status/index.js +5 -3
  280. package/dist/screen/index.js +3 -0
  281. package/dist/scroll-area/index.js +1 -1
  282. package/dist/search-field/index.js +8 -3
  283. package/dist/secret-field/index.js +19 -0
  284. package/dist/section-header/index.js +4 -0
  285. package/dist/segmented-control/index.js +2 -2
  286. package/dist/sheet/index.js +9 -3
  287. package/dist/shortcuts-sheet/index.js +2 -0
  288. package/dist/sign-in-screen/index.js +25 -0
  289. package/dist/skeleton/index.js +3 -1
  290. package/dist/slider/index.js +2 -1
  291. package/dist/sortable/index.js +4 -3
  292. package/dist/spinner/index.js +2 -1
  293. package/dist/split-button/index.js +17 -5
  294. package/dist/spotlight/index.js +7 -1
  295. package/dist/stack/index.js +2 -0
  296. package/dist/stage-timeline/index.js +6 -3
  297. package/dist/status-dot/index.js +6 -2
  298. package/dist/stepper/index.js +7 -3
  299. package/dist/streaming-text/index.js +2 -1
  300. package/dist/survey/index.js +24 -14
  301. package/dist/switch/index.js +6 -2
  302. package/dist/system-state/index.js +12 -4
  303. package/dist/tab-bar/index.js +10 -2
  304. package/dist/tabs/index.js +10 -2
  305. package/dist/tags-input/index.js +8 -5
  306. package/dist/text/index.js +4 -0
  307. package/dist/textarea/index.js +5 -4
  308. package/dist/thinking/index.js +4 -1
  309. package/dist/tile-rail/index.js +10 -0
  310. package/dist/time-field/index.js +15 -7
  311. package/dist/time-range-control/index.js +26 -12
  312. package/dist/timeline/index.js +2 -2
  313. package/dist/toast/index.js +4 -2
  314. package/dist/toolbar/index.js +3 -2
  315. package/dist/tour/index.js +12 -10
  316. package/dist/transcript/index.js +28 -0
  317. package/dist/truncation-notice/index.js +2 -2
  318. package/dist/update-notice/index.js +15 -8
  319. package/dist/video-player/index.js +26 -2
  320. package/dist/viewfinder/index.js +12 -4
  321. package/dist/widget/index.js +11 -4
  322. package/dist/wizard/index.js +7 -4
  323. package/package.json +13 -13
  324. package/dist/chunk-2PKYGLQ6.js +0 -268
  325. package/dist/chunk-2SWKL3AJ.js +0 -466
  326. package/dist/chunk-2TXERVVA.js +0 -1081
  327. package/dist/chunk-3DUWIYV5.js +0 -437
  328. package/dist/chunk-3NMD74ZU.js +0 -4
  329. package/dist/chunk-4DS5ZWVC.js +0 -83
  330. package/dist/chunk-6YAQBXB3.js +0 -93
  331. package/dist/chunk-74FLKD24.js +0 -237
  332. package/dist/chunk-CMTVNF3D.js +0 -104
  333. package/dist/chunk-DN7MNQIP.js +0 -799
  334. package/dist/chunk-DVGBZ3TX.js +0 -455
  335. package/dist/chunk-F3H33DQX.js +0 -300
  336. package/dist/chunk-FAJI7BSC.js +0 -443
  337. package/dist/chunk-G3AFC24V.js +0 -60
  338. package/dist/chunk-HJLPZA4X.js +0 -369
  339. package/dist/chunk-HYEOQWT7.js +0 -647
  340. package/dist/chunk-IDM7JJMO.js +0 -110
  341. package/dist/chunk-IVKMZ7BB.js +0 -326
  342. package/dist/chunk-IXKWIFWZ.js +0 -334
  343. package/dist/chunk-JV5YOTOB.js +0 -164
  344. package/dist/chunk-KFJGFLMW.js +0 -158
  345. package/dist/chunk-LQP4KEXZ.js +0 -214
  346. package/dist/chunk-NTQ2F3AU.js +0 -257
  347. package/dist/chunk-O5V4TG3V.js +0 -329
  348. package/dist/chunk-OWAMM2DK.js +0 -280
  349. package/dist/chunk-PID3NJB7.js +0 -405
  350. package/dist/chunk-QDZGFXQD.js +0 -176
  351. package/dist/chunk-QPWDDJJ4.js +0 -385
  352. package/dist/chunk-ROCUG24E.js +0 -416
  353. package/dist/chunk-RU3ZPNL6.js +0 -1986
  354. package/dist/chunk-RXSCIO6W.js +0 -153
  355. package/dist/chunk-SKWO3SZF.js +0 -2284
  356. package/dist/chunk-UQGBTPXH.js +0 -218
  357. package/dist/chunk-UYGDJWMN.js +0 -273
  358. package/dist/chunk-W74TXYFB.js +0 -107
  359. package/dist/chunk-WRDSPUE7.js +0 -417
  360. package/dist/chunk-XBZGDDMR.js +0 -105
  361. package/dist/chunk-XN4KG3P4.js +0 -1040
  362. package/dist/chunk-XQXMLMH3.js +0 -211
  363. package/dist/chunk-ZECZOOSB.js +0 -245
  364. /package/dist/{chunk-VFCUIDRT.js → chunk-3BKLBYPK.js} +0 -0
  365. /package/dist/{chunk-GEIGMWNF.js → chunk-QNZII37O.js} +0 -0
@@ -1,45 +1,59 @@
1
- import { camInk, useViewfinderLabels, useAnalyzerCopy, GlassIconButton, decorativeProps, untabbableProps, camMeta, pressedProps } from './chunk-HJLPZA4X.js';
1
+ import { camInk, useViewfinderLabels, camToneColour, BusySpinner, busyProps, busyStyle, useAnalyzerCopy, HintTrail, camToneEdge, GlassIconButton, decorativeProps, untabbableProps, PillRemoveButton, disabledProps, useEnterFade, disabledStyle, camGlass, camMeta, pressedProps } from './chunk-OCHPK5YV.js';
2
+ import { Badge } from './chunk-LGNTP5XA.js';
3
+ import { isAndroidIdiom } from './chunk-TH4PW2WU.js';
2
4
  import { useLoamLocale } from './chunk-APCWFOZW.js';
3
- import { Icon } from './chunk-UXGIW7OK.js';
5
+ import { Icon } from './chunk-PCEFCOLN.js';
4
6
  import { useReducedMotion } from './chunk-J64KGCGX.js';
5
7
  import * as React3 from 'react';
6
8
  import { Animated, View, Text, Pressable, Easing, Dimensions, ScrollView } from 'react-native';
7
- import Svg2, { Path, Circle, Defs, LinearGradient, Stop, Rect, Line } from 'react-native-svg';
9
+ import Svg2, { Path, Circle, Defs, LinearGradient, Stop, Rect, Mask, Line } from 'react-native-svg';
8
10
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
9
- import { TRACK_BAND_BOTTOM, confidenceTone, TRACKING_MOTION, confidenceLabel, trackCountLabel, trackTone, chipRoom, chipAnchor, chipSlot, visibleChips, MAX_CHIPS, trackingSummaryLabel, readBatchLabel } from '@btndprojects/loam-analyzer';
11
+ import { TRACK_BAND_BOTTOM, confidenceTone, TRACKING_MOTION, confidenceLabel, trackCountLabel, trackTone, chipRoom, chipAnchor, chipSlot, visibleChips, MAX_CHIPS, trackingSummaryLabel, highlightWeight, contourPath, boxPath, readBatchLabel } from '@btndprojects/loam-analyzer';
10
12
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
11
13
 
12
14
  var RING_R = 46;
13
15
  var RING_C = 2 * Math.PI * RING_R;
14
16
  var RING_STROKE = 6;
15
- function CountdownRing({ value, label, labels }) {
17
+ function CountdownRing({
18
+ value,
19
+ label,
20
+ labels,
21
+ tone = "neutral",
22
+ size = "md",
23
+ variant = "ring",
24
+ loading = false,
25
+ motion = "full"
26
+ }) {
16
27
  const t = useViewfinderLabels(labels);
17
28
  const theme = useLoamTheme("viewfinder");
18
29
  const reduced = useReducedMotion();
19
30
  const { styles } = useStyles(controlSheet);
20
31
  const pct2 = Math.min(100, Math.max(0, value));
21
- const still = reduced || theme.reduceMotion;
32
+ const still = reduced || theme.reduceMotion || motion !== "full" || variant === "number";
33
+ const accent = camToneColour(theme, tone) ?? theme.color.good;
34
+ const stroke = size === "sm" ? RING_STROKE - 2 : size === "lg" ? RING_STROKE + 2 : RING_STROKE;
22
35
  return /* @__PURE__ */ jsx(
23
36
  View,
24
37
  {
25
38
  accessibilityRole: "progressbar",
26
39
  role: "progressbar",
27
40
  accessibilityLabel: label ?? t.autoCapturing,
28
- accessibilityValue: { min: 0, max: 100, now: Math.round(pct2) },
41
+ accessibilityValue: loading ? void 0 : { min: 0, max: 100, now: Math.round(pct2) },
29
42
  style: styles.ringRoot,
30
43
  ...{
31
- "aria-valuenow": Math.round(pct2),
44
+ "aria-valuenow": loading ? void 0 : Math.round(pct2),
32
45
  "aria-valuemin": 0,
33
46
  "aria-valuemax": 100
34
47
  },
35
- children: still ? /* @__PURE__ */ jsx(Text, { style: styles.ringNumber, children: String(Math.round(pct2)) }) : /* @__PURE__ */ jsx(Svg2, { width: "100%", height: "100%", viewBox: "0 0 100 100", children: /* @__PURE__ */ jsx(
48
+ ...busyProps(loading),
49
+ children: loading ? /* @__PURE__ */ jsx(BusySpinner, { color: accent }) : still ? /* @__PURE__ */ jsx(Text, { style: [styles.ringNumber, { color: accent }], children: String(Math.round(pct2)) }) : /* @__PURE__ */ jsx(Svg2, { width: "100%", height: "100%", viewBox: "0 0 100 100", children: /* @__PURE__ */ jsx(
36
50
  Circle,
37
51
  {
38
52
  cx: 50,
39
53
  cy: 50,
40
54
  r: RING_R,
41
- stroke: theme.color.good,
42
- strokeWidth: RING_STROKE,
55
+ stroke: accent,
56
+ strokeWidth: stroke,
43
57
  strokeLinecap: "round",
44
58
  strokeDasharray: RING_C,
45
59
  strokeDashoffset: RING_C * (1 - pct2 / 100),
@@ -59,22 +73,43 @@ function ShutterButton({
59
73
  label,
60
74
  labels,
61
75
  onPress,
62
- onBlocked
76
+ onBlocked,
77
+ variant = "solid",
78
+ size = "md",
79
+ tone = "neutral",
80
+ motion = "full",
81
+ loading = false,
82
+ leading,
83
+ trailing,
84
+ fullWidth = false
63
85
  }) {
64
86
  const t = useViewfinderLabels(labels);
65
87
  const theme = useLoamTheme("viewfinder");
66
88
  const { styles } = useStyles(controlSheet, { platform, enabled });
67
- const glyphColour = enabled ? theme.media.onInk : camInk(theme);
89
+ const outline = variant === "outline" && enabled;
90
+ const glyphColour = enabled && !outline ? theme.media.onInk : camInk(theme);
91
+ const accent = enabled ? camToneColour(theme, tone) : void 0;
92
+ const base = { ios: theme.space[72], android: theme.space[68], web: theme.space[64] }[platform] + theme.space[2];
93
+ const diameter = size === "sm" ? base - theme.space[8] : size === "lg" ? base + theme.space[8] : base;
94
+ const still = motion !== "full" || theme.reduceMotion;
68
95
  if (mode === "continuous") return null;
69
- return /* @__PURE__ */ jsxs(
96
+ const shutter = /* @__PURE__ */ jsxs(
70
97
  Pressable,
71
98
  {
72
99
  accessibilityRole: "button",
73
100
  accessibilityLabel: label ?? t.capture,
74
101
  accessibilityState: { disabled: !enabled },
75
102
  testID: enabled ? "loam-shutter-open" : "loam-shutter-blocked",
76
- style: styles.shutter,
103
+ style: ({ pressed }) => [
104
+ styles.shutter,
105
+ size === "md" ? null : { width: diameter, height: diameter },
106
+ accent ? { borderColor: accent } : null,
107
+ pressed && !still && !loading ? { opacity: theme.state.pressedOpacity } : null,
108
+ busyStyle(theme, loading)
109
+ ],
110
+ ...busyProps(loading),
77
111
  onPress: () => {
112
+ if (loading) return;
78
113
  if (!enabled) {
79
114
  onBlocked?.(blockedToast ?? "");
80
115
  return;
@@ -82,35 +117,142 @@ function ShutterButton({
82
117
  onPress?.();
83
118
  },
84
119
  children: [
85
- /* @__PURE__ */ jsx(View, { style: styles.shutterFill, children: /* @__PURE__ */ jsx(
86
- Icon,
120
+ /* @__PURE__ */ jsx(
121
+ View,
87
122
  {
88
- name: enabled ? "circle" : "lock",
89
- size: enabled ? theme.icon.lg : theme.icon.md,
90
- color: glyphColour
123
+ style: [
124
+ styles.shutterFill,
125
+ outline ? { backgroundColor: theme.black.a12, borderWidth: theme.borderWidth.base, borderColor: theme.white.a5 } : null
126
+ ],
127
+ children: loading ? /* @__PURE__ */ jsx(BusySpinner, { color: glyphColour }) : /* @__PURE__ */ jsx(
128
+ Icon,
129
+ {
130
+ name: enabled ? "circle" : "lock",
131
+ size: enabled ? theme.icon.lg : theme.icon.md,
132
+ color: glyphColour
133
+ }
134
+ )
91
135
  }
92
- ) }),
136
+ ),
93
137
  typeof countdown === "number" ? /* @__PURE__ */ jsx(CountdownRing, { value: countdown, labels }) : null
94
138
  ]
95
139
  }
96
140
  );
141
+ if (!leading && !trailing && !fullWidth) return shutter;
142
+ const side = (name, end) => {
143
+ if (!name && !fullWidth) return null;
144
+ return /* @__PURE__ */ jsx(
145
+ View,
146
+ {
147
+ "aria-hidden": true,
148
+ testID: end ? "loam-shutter-trailing" : "loam-shutter-leading",
149
+ style: fullWidth ? { flex: 1, alignItems: end ? "flex-end" : "flex-start" } : null,
150
+ children: name ? /* @__PURE__ */ jsx(Icon, { name, size: theme.icon.lg, color: camInk(theme) }) : null
151
+ }
152
+ );
153
+ };
154
+ return /* @__PURE__ */ jsxs(
155
+ View,
156
+ {
157
+ testID: "loam-shutter-row",
158
+ style: [
159
+ { flexDirection: "row", alignItems: "center", gap: theme.space[16] },
160
+ fullWidth ? { alignSelf: "stretch", justifyContent: "space-between" } : null
161
+ ],
162
+ children: [
163
+ side(leading, false),
164
+ shutter,
165
+ side(trailing, true)
166
+ ]
167
+ }
168
+ );
97
169
  }
98
- function ContinuousNotice({ text, copy }) {
170
+ function ContinuousNotice({
171
+ text,
172
+ copy,
173
+ tone = "neutral",
174
+ variant = "glass",
175
+ dismissible = false,
176
+ onDismiss,
177
+ action,
178
+ icon = "barcode",
179
+ size = "md",
180
+ motion = "full",
181
+ loading = false
182
+ }) {
99
183
  const words = useAnalyzerCopy(copy);
184
+ const t = useViewfinderLabels();
100
185
  const theme = useLoamTheme("viewfinder");
186
+ const reduced = useReducedMotion();
101
187
  const { styles } = useStyles(controlSheet);
102
- const ink = camInk(theme);
103
- return /* @__PURE__ */ jsxs(View, { style: styles.notice, children: [
104
- /* @__PURE__ */ jsx(Icon, { name: "barcode", size: theme.icon.sm, color: ink }),
105
- /* @__PURE__ */ jsx(Text, { style: [styles.noticeText, { color: ink }], children: text ?? words.continuousNotice })
106
- ] });
188
+ const accent = camToneColour(theme, tone);
189
+ const solid = variant === "solid";
190
+ const ink = solid ? theme.media.onInk : camInk(theme);
191
+ const iconColour = solid ? ink : accent ?? ink;
192
+ const fade = React3.useRef(new Animated.Value(0)).current;
193
+ const still = motion !== "full" || reduced || theme.reduceMotion;
194
+ React3.useEffect(() => {
195
+ if (still) {
196
+ fade.setValue(1);
197
+ return;
198
+ }
199
+ Animated.timing(fade, {
200
+ toValue: 1,
201
+ duration: theme.motion.swap.duration,
202
+ easing: Easing.bezier(...theme.motion.swap.easing),
203
+ useNativeDriver: true
204
+ }).start();
205
+ }, [still, fade, theme.motion.swap.duration, theme.motion.swap.easing]);
206
+ return /* @__PURE__ */ jsxs(
207
+ Animated.View,
208
+ {
209
+ testID: "loam-continuous-notice",
210
+ style: [
211
+ styles.notice,
212
+ size === "sm" ? { minHeight: theme.ctl.sm, paddingVertical: theme.space[4] } : null,
213
+ solid ? { backgroundColor: accent ?? theme.media.ink, borderColor: accent ?? theme.media.ink } : camToneEdge(theme, tone),
214
+ variant === "outline" ? { backgroundColor: "transparent" } : null,
215
+ { opacity: still ? 1 : fade },
216
+ busyStyle(theme, false)
217
+ ],
218
+ ...busyProps(loading),
219
+ children: [
220
+ loading ? /* @__PURE__ */ jsx(BusySpinner, { color: iconColour }) : icon ? /* @__PURE__ */ jsx(Icon, { name: icon, size: theme.icon.sm, color: iconColour }) : null,
221
+ /* @__PURE__ */ jsx(
222
+ Text,
223
+ {
224
+ style: [
225
+ styles.noticeText,
226
+ size === "sm" ? { fontSize: theme.fontSize[12] } : null,
227
+ { color: ink }
228
+ ],
229
+ children: text ?? words.continuousNotice
230
+ }
231
+ ),
232
+ /* @__PURE__ */ jsx(
233
+ HintTrail,
234
+ {
235
+ action,
236
+ dismissible: dismissible || onDismiss != null,
237
+ onDismiss,
238
+ label: t.dismiss
239
+ }
240
+ )
241
+ ]
242
+ }
243
+ );
107
244
  }
108
245
  function TorchToggle({
109
246
  on = false,
110
247
  available = true,
111
248
  label,
112
249
  labels,
113
- onChange
250
+ onChange,
251
+ variant,
252
+ size,
253
+ disabled,
254
+ loading,
255
+ tone
114
256
  }) {
115
257
  const t = useViewfinderLabels(labels);
116
258
  if (!available) return null;
@@ -120,6 +262,11 @@ function TorchToggle({
120
262
  icon: "flash",
121
263
  label: label ?? t.torch,
122
264
  on,
265
+ variant,
266
+ size,
267
+ disabled,
268
+ loading,
269
+ tone,
123
270
  onPress: () => onChange?.(!on)
124
271
  }
125
272
  );
@@ -128,20 +275,68 @@ function ViewfinderGridToggle({
128
275
  on = false,
129
276
  label,
130
277
  labels,
131
- onChange
278
+ onChange,
279
+ variant,
280
+ size,
281
+ disabled,
282
+ loading,
283
+ tone
132
284
  }) {
133
285
  const t = useViewfinderLabels(labels);
134
- return /* @__PURE__ */ jsx(GlassIconButton, { icon: "grid", label: label ?? t.grid, on, onPress: () => onChange?.(!on) });
286
+ return /* @__PURE__ */ jsx(
287
+ GlassIconButton,
288
+ {
289
+ icon: "grid",
290
+ label: label ?? t.grid,
291
+ on,
292
+ variant,
293
+ size,
294
+ disabled,
295
+ loading,
296
+ tone,
297
+ onPress: () => onChange?.(!on)
298
+ }
299
+ );
135
300
  }
136
- function FlipButton({ label, labels, onFlip }) {
301
+ function FlipButton({
302
+ label,
303
+ labels,
304
+ disabled = false,
305
+ onFlip,
306
+ variant,
307
+ size,
308
+ loading,
309
+ leadingIcon = "flip",
310
+ tone,
311
+ motion,
312
+ trailingIcon,
313
+ fullWidth
314
+ }) {
137
315
  const t = useViewfinderLabels(labels);
138
- return /* @__PURE__ */ jsx(GlassIconButton, { icon: "flip", label: label ?? t.flipCamera, onPress: onFlip });
316
+ return /* @__PURE__ */ jsx(
317
+ GlassIconButton,
318
+ {
319
+ icon: leadingIcon,
320
+ label: label ?? t.flipCamera,
321
+ disabled,
322
+ variant,
323
+ size,
324
+ loading,
325
+ tone,
326
+ motion,
327
+ trailingIcon,
328
+ fullWidth,
329
+ onPress: onFlip
330
+ }
331
+ );
139
332
  }
140
333
  function LensStop({
141
334
  stop,
142
335
  on,
143
336
  onPick,
144
- labels
337
+ labels,
338
+ size = "md",
339
+ disabled = false
145
340
  }) {
146
341
  const t = useViewfinderLabels(labels);
147
342
  const theme = useLoamTheme("viewfinder");
@@ -151,9 +346,10 @@ function LensStop({
151
346
  {
152
347
  accessibilityRole: "button",
153
348
  accessibilityLabel: t.zoomStop(stop),
154
- accessibilityState: { selected: on },
155
- style: styles.lensStop,
156
- hitSlop: Math.max(0, (theme.hit.lg - theme.ctl.md) / 2),
349
+ accessibilityState: { selected: on, ...disabled ? { disabled: true } : null },
350
+ disabled,
351
+ style: [styles.lensStop, { width: theme.ctl[size], height: theme.ctl[size] }],
352
+ hitSlop: Math.max(0, (theme.hit.lg - theme.ctl[size]) / 2),
157
353
  onPress: onPick,
158
354
  ...pressedProps(on),
159
355
  children: /* @__PURE__ */ jsx(Text, { style: [styles.lensLabel, { color: on ? theme.media.onInk : camInk(theme) }], children: t.zoomStop(stop) })
@@ -165,20 +361,49 @@ function LensPicker({
165
361
  value = 1,
166
362
  label,
167
363
  labels,
168
- onChange
364
+ onChange,
365
+ size = "md",
366
+ variant = "glass",
367
+ disabled = false,
368
+ loading = false,
369
+ tone = "neutral",
370
+ orientation = "horizontal",
371
+ fullWidth = false,
372
+ density = "comfortable"
169
373
  }) {
170
374
  const t = useViewfinderLabels(labels);
375
+ const theme = useLoamTheme("viewfinder");
171
376
  const { styles } = useStyles(controlSheet);
172
- return /* @__PURE__ */ jsx(View, { role: "group", accessibilityLabel: label ?? t.zoom, style: styles.lensColumn, children: stops.map((stop) => /* @__PURE__ */ jsx(
173
- LensStop,
377
+ const blocked = disabled || loading;
378
+ return /* @__PURE__ */ jsx(
379
+ View,
174
380
  {
175
- stop,
176
- on: stop === value,
177
- labels,
178
- onPick: () => onChange?.(stop)
179
- },
180
- stop
181
- )) });
381
+ role: "group",
382
+ accessibilityLabel: label ?? t.zoom,
383
+ style: [
384
+ styles.lensColumn,
385
+ orientation === "vertical" ? { flexDirection: "column" } : null,
386
+ density === "compact" ? { padding: theme.space[2], gap: theme.space[0] } : null,
387
+ fullWidth ? { alignSelf: "stretch", justifyContent: "space-around" } : null,
388
+ variant === "outline" ? { backgroundColor: "transparent" } : null,
389
+ camToneEdge(theme, tone),
390
+ disabled ? { opacity: theme.state.disabledOpacity } : busyStyle(theme, loading)
391
+ ],
392
+ ...busyProps(loading),
393
+ children: stops.map((stop) => /* @__PURE__ */ jsx(
394
+ LensStop,
395
+ {
396
+ stop,
397
+ on: stop === value,
398
+ labels,
399
+ size,
400
+ disabled: blocked,
401
+ onPick: () => onChange?.(stop)
402
+ },
403
+ stop
404
+ ))
405
+ }
406
+ );
182
407
  }
183
408
  var controlSheet = createStyleSheet((theme) => ({
184
409
  ringRoot: {
@@ -205,15 +430,19 @@ var controlSheet = createStyleSheet((theme) => ({
205
430
  borderWidth: theme.borderWidth.strong,
206
431
  variants: {
207
432
  platform: {
208
- ios: { width: theme.space[76], height: theme.space[76], borderRadius: theme.radius.full },
433
+ ios: {
434
+ width: theme.space[72] + theme.space[2],
435
+ height: theme.space[72] + theme.space[2],
436
+ borderRadius: theme.radius.full
437
+ },
209
438
  android: {
210
- width: theme.space[72],
211
- height: theme.space[72],
439
+ width: theme.space[68] + theme.space[2],
440
+ height: theme.space[68] + theme.space[2],
212
441
  borderRadius: theme.radius["2xl"]
213
442
  },
214
443
  web: {
215
- width: theme.space[68],
216
- height: theme.space[68],
444
+ width: theme.space[64] + theme.space[2],
445
+ height: theme.space[64] + theme.space[2],
217
446
  borderRadius: theme.radius["2xl"]
218
447
  }
219
448
  },
@@ -253,7 +482,7 @@ var controlSheet = createStyleSheet((theme) => ({
253
482
  alignSelf: "stretch",
254
483
  paddingHorizontal: theme.space[12],
255
484
  paddingVertical: theme.space[8],
256
- borderRadius: theme.radius.sm,
485
+ borderRadius: theme.radius.md,
257
486
  backgroundColor: theme.black.a12,
258
487
  borderWidth: theme.borderWidth.base,
259
488
  borderColor: theme.white.a5
@@ -293,20 +522,27 @@ var controlSheet = createStyleSheet((theme) => ({
293
522
  },
294
523
  lensLabel: {
295
524
  fontFamily: theme.font.sans,
296
- fontSize: theme.fontSize[11],
297
- fontWeight: theme.fontWeight.medium,
525
+ fontSize: theme.fontSize[12],
526
+ fontWeight: theme.fontWeight.semibold,
298
527
  fontVariant: ["tabular-nums"]
299
528
  }
300
529
  }));
301
- function ScanLine({ active = true, band, travel }) {
530
+ function ScanLine({
531
+ active = true,
532
+ band,
533
+ travel,
534
+ tone = "neutral",
535
+ loading = false
536
+ }) {
302
537
  const theme = useLoamTheme("viewfinder");
303
538
  const reduced = useReducedMotion();
304
539
  const { styles } = useStyles(overlaySheet);
540
+ const accent = camToneColour(theme, tone) ?? theme.color.good;
305
541
  const height = band ?? theme.space[80];
306
542
  const thickness = theme.borderWidth.heavy;
307
543
  const distance = travel ?? height - thickness;
308
544
  const offset = React3.useRef(new Animated.Value(0)).current;
309
- const still = reduced || theme.reduceMotion;
545
+ const still = reduced || theme.reduceMotion || loading;
310
546
  React3.useEffect(() => {
311
547
  if (!active || still) {
312
548
  offset.setValue(0);
@@ -325,27 +561,31 @@ function ScanLine({ active = true, band, travel }) {
325
561
  }, [active, still, offset, theme.loop.beacon, theme.easing.inOut]);
326
562
  if (!active) return null;
327
563
  const translateY = still ? distance / 2 : offset.interpolate({ inputRange: [0, 1], outputRange: [0, distance] });
328
- return /* @__PURE__ */ jsx(
564
+ return /* @__PURE__ */ jsxs(
329
565
  View,
330
566
  {
331
567
  accessible: false,
332
568
  testID: still ? "loam-scan-band-static" : "loam-scan-band",
333
- style: [styles.scanBand, { height }],
569
+ style: [styles.scanBand, { height }, busyStyle(theme, loading)],
334
570
  ...decorativeProps(),
335
- children: /* @__PURE__ */ jsx(
336
- Animated.View,
337
- {
338
- style: [styles.scanLine, { height: thickness, transform: [{ translateY }] }],
339
- children: /* @__PURE__ */ jsxs(Svg2, { width: "100%", height: thickness, children: [
340
- /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(LinearGradient, { id: "loam-cam-scan", x1: "0", y1: "0", x2: "1", y2: "0", children: [
341
- /* @__PURE__ */ jsx(Stop, { offset: "0", stopColor: theme.color.good, stopOpacity: theme.opacity[0] }),
342
- /* @__PURE__ */ jsx(Stop, { offset: "0.5", stopColor: theme.color.good, stopOpacity: theme.opacity[100] }),
343
- /* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: theme.color.good, stopOpacity: theme.opacity[0] })
344
- ] }) }),
345
- /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: thickness, fill: "url(#loam-cam-scan)" })
346
- ] })
347
- }
348
- )
571
+ ...busyProps(loading),
572
+ children: [
573
+ loading ? /* @__PURE__ */ jsx(View, { style: styles.busyCentre, children: /* @__PURE__ */ jsx(BusySpinner, { color: accent }) }) : null,
574
+ /* @__PURE__ */ jsx(
575
+ Animated.View,
576
+ {
577
+ style: [styles.scanLine, { height: thickness, transform: [{ translateY }] }],
578
+ children: /* @__PURE__ */ jsxs(Svg2, { width: "100%", height: thickness, children: [
579
+ /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(LinearGradient, { id: "loam-cam-scan", x1: "0", y1: "0", x2: "1", y2: "0", children: [
580
+ /* @__PURE__ */ jsx(Stop, { offset: "0", stopColor: accent, stopOpacity: theme.opacity[0] }),
581
+ /* @__PURE__ */ jsx(Stop, { offset: "0.5", stopColor: accent, stopOpacity: theme.opacity[100] }),
582
+ /* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: accent, stopOpacity: theme.opacity[0] })
583
+ ] }) }),
584
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: thickness, fill: "url(#loam-cam-scan)" })
585
+ ] })
586
+ }
587
+ )
588
+ ]
349
589
  }
350
590
  );
351
591
  }
@@ -369,7 +609,9 @@ function GuideOverlay({
369
609
  pass = false,
370
610
  dimmed = false,
371
611
  hint,
372
- scanning = true
612
+ scanning = true,
613
+ tone = "neutral",
614
+ loading = false
373
615
  }) {
374
616
  const theme = useLoamTheme("viewfinder");
375
617
  const { styles } = useStyles(overlaySheet, { pass, dimmed });
@@ -384,7 +626,7 @@ function GuideOverlay({
384
626
  }, [pass, snap, theme.motion.swap.duration, theme.motion.swap.easing]);
385
627
  if (kind === "none") return null;
386
628
  const box = GUIDE_BOX[kind];
387
- const colour = pass ? theme.color.good : theme.white.a12;
629
+ const colour = pass ? camToneColour(theme, tone) ?? theme.color.good : theme.white.a12;
388
630
  const scrim = box.hole && kind !== "circle" ? theme.black.a9 : void 0;
389
631
  const reach = Dimensions.get("screen").height;
390
632
  const bandGrow = box.heightFlex === void 0 ? null : { flexGrow: (100 - box.heightFlex) / 2 };
@@ -394,8 +636,9 @@ function GuideOverlay({
394
636
  {
395
637
  accessible: false,
396
638
  testID: `loam-guide-${kind}-${pass ? "pass" : "wait"}`,
397
- style: [styles.guideRoot, box.hole ? styles.guideRootBleed : null],
639
+ style: [styles.guideRoot, box.hole ? styles.guideRootBleed : null, busyStyle(theme, loading)],
398
640
  ...decorativeProps(),
641
+ ...busyProps(loading),
399
642
  children: [
400
643
  /* @__PURE__ */ jsx(View, { style: [styles.scrimBand, bandGrow, scrim ? { backgroundColor: scrim } : null] }),
401
644
  /* @__PURE__ */ jsxs(
@@ -446,7 +689,7 @@ function GuideOverlay({
446
689
  ),
447
690
  /* @__PURE__ */ jsx(View, { style: [styles.circleGuide, { borderColor: colour }] })
448
691
  ] }) : null,
449
- kind === "line" ? /* @__PURE__ */ jsx(View, { style: [styles.lineGuide, { borderColor: colour }], children: /* @__PURE__ */ jsx(ScanLine, { active: scanning }) }) : null,
692
+ kind === "line" ? /* @__PURE__ */ jsx(View, { style: [styles.lineGuide, { borderColor: colour }], children: /* @__PURE__ */ jsx(ScanLine, { active: scanning, tone }) }) : null,
450
693
  kind === "silhouette" ? /* @__PURE__ */ jsxs(Svg2, { viewBox: "0 0 100 44", width: "100%", height: "100%", preserveAspectRatio: "xMidYMid meet", children: [
451
694
  /* @__PURE__ */ jsx(
452
695
  Path,
@@ -474,22 +717,44 @@ function GuideOverlay({
474
717
  }
475
718
  );
476
719
  }
477
- function ViewfinderGridOverlay({ visible = false }) {
720
+ function ViewfinderGridOverlay({
721
+ visible = false,
722
+ tone = "neutral",
723
+ loading = false
724
+ }) {
478
725
  const { styles } = useStyles(overlaySheet);
726
+ const theme = useLoamTheme("viewfinder");
727
+ const accent = camToneColour(theme, tone);
728
+ const tint = accent ? { backgroundColor: accent } : null;
479
729
  if (!visible) return null;
480
- return /* @__PURE__ */ jsxs(View, { accessible: false, testID: "loam-grid-overlay", style: styles.gridRoot, ...decorativeProps(), children: [
481
- /* @__PURE__ */ jsx(View, { style: styles.gridV1 }),
482
- /* @__PURE__ */ jsx(View, { style: styles.gridV2 }),
483
- /* @__PURE__ */ jsx(View, { style: styles.gridH1 }),
484
- /* @__PURE__ */ jsx(View, { style: styles.gridH2 })
485
- ] });
730
+ return /* @__PURE__ */ jsxs(
731
+ View,
732
+ {
733
+ accessible: false,
734
+ testID: "loam-grid-overlay",
735
+ style: [styles.gridRoot, busyStyle(theme, loading)],
736
+ ...decorativeProps(),
737
+ ...busyProps(loading),
738
+ children: [
739
+ /* @__PURE__ */ jsx(View, { style: [styles.gridV1, tint] }),
740
+ /* @__PURE__ */ jsx(View, { style: [styles.gridV2, tint] }),
741
+ /* @__PURE__ */ jsx(View, { style: [styles.gridH1, tint] }),
742
+ /* @__PURE__ */ jsx(View, { style: [styles.gridH2, tint] })
743
+ ]
744
+ }
745
+ );
486
746
  }
487
- function FocusPulse({ point }) {
747
+ function FocusPulse({
748
+ point,
749
+ tone,
750
+ loading
751
+ }) {
488
752
  const theme = useLoamTheme("viewfinder");
489
753
  const reduced = useReducedMotion();
490
754
  const { styles } = useStyles(overlaySheet);
491
755
  const phase = React3.useRef(new Animated.Value(0)).current;
492
- const still = reduced || theme.reduceMotion;
756
+ const still = reduced || theme.reduceMotion || loading;
757
+ const accent = camToneColour(theme, tone) ?? theme.color.warn;
493
758
  React3.useEffect(() => {
494
759
  if (still) {
495
760
  phase.setValue(1);
@@ -514,28 +779,38 @@ function FocusPulse({ point }) {
514
779
  {
515
780
  left: `${point.x * 100}%`,
516
781
  top: `${point.y * 100}%`,
517
- borderColor: theme.color.warn,
782
+ borderColor: accent,
518
783
  opacity,
519
784
  transform: [{ scale }]
520
- }
785
+ },
786
+ busyStyle(theme, loading)
521
787
  ],
522
788
  ...decorativeProps(),
789
+ ...busyProps(loading),
523
790
  children: /* @__PURE__ */ jsxs(Svg2, { viewBox: "0 0 24 24", width: theme.icon.lg, height: theme.icon.lg, children: [
524
- /* @__PURE__ */ jsx(Line, { x1: 12, y1: 6, x2: 12, y2: 18, stroke: theme.color.warn, strokeWidth: 1 }),
525
- /* @__PURE__ */ jsx(Line, { x1: 6, y1: 12, x2: 18, y2: 12, stroke: theme.color.warn, strokeWidth: 1 })
791
+ /* @__PURE__ */ jsx(Line, { x1: 12, y1: 6, x2: 12, y2: 18, stroke: accent, strokeWidth: 1 }),
792
+ /* @__PURE__ */ jsx(Line, { x1: 6, y1: 12, x2: 18, y2: 12, stroke: accent, strokeWidth: 1 })
526
793
  ] })
527
794
  }
528
795
  );
529
796
  }
530
797
  function FocusIndicator({
531
798
  point = null,
532
- pulseKey = 0
799
+ pulseKey = 0,
800
+ tone = "neutral",
801
+ loading = false
533
802
  }) {
534
803
  if (!point) return null;
535
- return /* @__PURE__ */ jsx(FocusPulse, { point }, pulseKey);
804
+ return /* @__PURE__ */ jsx(FocusPulse, { point, tone, loading }, pulseKey);
536
805
  }
537
- function FocusTapZone({ onFocusPoint }) {
806
+ function FocusTapZone({
807
+ onFocusPoint,
808
+ tone = "neutral",
809
+ loading = false
810
+ }) {
811
+ const theme = useLoamTheme("viewfinder");
538
812
  const { styles } = useStyles(overlaySheet);
813
+ const accent = camToneColour(theme, tone);
539
814
  const size = React3.useRef({ width: 0, height: 0 });
540
815
  const onLayout = (e) => {
541
816
  size.current = {
@@ -551,10 +826,11 @@ function FocusTapZone({ onFocusPoint }) {
551
826
  testID: "loam-focus-zone",
552
827
  ...decorativeProps(),
553
828
  ...untabbableProps(),
829
+ ...busyProps(loading),
554
830
  onLayout,
555
831
  style: styles.tapZone,
556
832
  onPress: (e) => {
557
- if (!onFocusPoint) return;
833
+ if (loading || !onFocusPoint) return;
558
834
  const { width, height } = size.current;
559
835
  if (width === 0 || height === 0) return;
560
836
  const { locationX, locationY } = e.nativeEvent;
@@ -562,7 +838,17 @@ function FocusTapZone({ onFocusPoint }) {
562
838
  x: Math.min(1, Math.max(0, locationX / width)),
563
839
  y: Math.min(1, Math.max(0, locationY / height))
564
840
  });
565
- }
841
+ },
842
+ children: ({ pressed }) => /* @__PURE__ */ jsxs(Fragment, { children: [
843
+ pressed && accent && !loading ? /* @__PURE__ */ jsx(
844
+ View,
845
+ {
846
+ testID: "loam-focus-zone-wash",
847
+ style: [styles.busyCentre, { backgroundColor: accent, opacity: theme.opacity[20] }]
848
+ }
849
+ ) : null,
850
+ loading ? /* @__PURE__ */ jsx(View, { style: styles.busyCentre, children: /* @__PURE__ */ jsx(BusySpinner, { color: accent ?? camInk(theme) }) }) : null
851
+ ] })
566
852
  }
567
853
  );
568
854
  }
@@ -656,7 +942,8 @@ var overlaySheet = createStyleSheet((theme) => ({
656
942
  fontSize: theme.fontSize[12],
657
943
  color: theme.media.ink,
658
944
  paddingHorizontal: theme.space[12],
659
- paddingVertical: theme.space[4],
945
+ height: theme.space[24],
946
+ lineHeight: theme.space[24],
660
947
  borderRadius: theme.radius.full,
661
948
  backgroundColor: theme.black.a12,
662
949
  borderWidth: theme.borderWidth.base,
@@ -755,6 +1042,16 @@ var overlaySheet = createStyleSheet((theme) => ({
755
1042
  borderRadius: theme.radius.sm,
756
1043
  borderWidth: theme.borderWidth.strong
757
1044
  },
1045
+ busyCentre: {
1046
+ pointerEvents: "none",
1047
+ position: "absolute",
1048
+ top: theme.space[0],
1049
+ bottom: theme.space[0],
1050
+ left: theme.space[0],
1051
+ right: theme.space[0],
1052
+ alignItems: "center",
1053
+ justifyContent: "center"
1054
+ },
758
1055
  tapZone: {
759
1056
  position: "absolute",
760
1057
  top: theme.space[0],
@@ -788,13 +1085,27 @@ function TrackChip({
788
1085
  anchor = "start",
789
1086
  room = 100,
790
1087
  staggerIndex = 0,
791
- frozen = false
1088
+ frozen = false,
1089
+ tone: toneProp,
1090
+ size = "md",
1091
+ variant = "glass",
1092
+ selected = false,
1093
+ leading,
1094
+ loading = false,
1095
+ disabled = false,
1096
+ motion = "full",
1097
+ removable = false,
1098
+ onRemove,
1099
+ removeLabel,
1100
+ labels
792
1101
  }) {
793
1102
  const theme = useLoamTheme("viewfinder");
1103
+ const t = useViewfinderLabels(labels);
794
1104
  const reduced = useReducedMotion();
795
1105
  const tone = confidenceTone(conf);
796
1106
  const { styles } = useStyles(trackingSheet, { slot, tone, anchor });
797
- const still = reduced || theme.reduceMotion || frozen;
1107
+ const dotTone = camToneColour(theme, toneProp);
1108
+ const still = reduced || theme.reduceMotion || frozen || motion !== "full";
798
1109
  const enter = React3.useRef(new Animated.Value(still ? 1 : 0)).current;
799
1110
  const delay = React3.useRef(staggerIndex * TRACKING_MOTION.chipStagger).current;
800
1111
  React3.useEffect(() => {
@@ -812,36 +1123,95 @@ function TrackChip({
812
1123
  anim.start();
813
1124
  return () => anim.stop();
814
1125
  }, [still, enter, delay, theme.motion.enter.duration, theme.motion.enter.easing]);
815
- return /* @__PURE__ */ jsx(View, { style: [styles.chipLane, { width: `${room}%` }], ...decorativeProps(), children: /* @__PURE__ */ jsxs(
816
- Animated.View,
1126
+ return /* @__PURE__ */ jsx(
1127
+ View,
817
1128
  {
818
- accessible: false,
819
- testID: `loam-track-chip-${slot}`,
820
- style: [styles.chip, { opacity: enter }],
821
- children: [
822
- /* @__PURE__ */ jsx(View, { style: styles.chipDot }),
823
- /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.chipLabel, children: label }),
824
- /* @__PURE__ */ jsx(Text, { style: styles.chipConf, children: confidenceLabel(conf) })
825
- ]
1129
+ style: [styles.chipLane, { width: `${room}%` }, removable ? { pointerEvents: "box-none" } : null],
1130
+ ...removable ? {} : decorativeProps(),
1131
+ children: /* @__PURE__ */ jsxs(
1132
+ Animated.View,
1133
+ {
1134
+ accessible: false,
1135
+ testID: `loam-track-chip-${slot}`,
1136
+ "aria-current": selected ? true : void 0,
1137
+ style: [
1138
+ styles.chip,
1139
+ size === "sm" ? { paddingHorizontal: theme.space[6], paddingVertical: theme.space[0] } : null,
1140
+ variant === "outline" ? { backgroundColor: "transparent" } : null,
1141
+ selected ? { backgroundColor: theme.white.a5, borderColor: theme.media.ink } : null,
1142
+ busyStyle(theme, loading),
1143
+ { opacity: loading || disabled ? theme.state.disabledOpacity : enter }
1144
+ ],
1145
+ ...busyProps(loading),
1146
+ ...disabledProps(disabled),
1147
+ children: [
1148
+ loading ? /* @__PURE__ */ jsx(BusySpinner, { color: camInk(theme) }) : leading ? /* @__PURE__ */ jsx(Icon, { name: leading, size: theme.icon.xs, color: camInk(theme) }) : /* @__PURE__ */ jsx(View, { style: [styles.chipDot, dotTone ? { backgroundColor: dotTone } : null] }),
1149
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.chipLabel, children: label }),
1150
+ /* @__PURE__ */ jsx(Text, { style: styles.chipConf, children: confidenceLabel(conf) }),
1151
+ removable ? /* @__PURE__ */ jsx(
1152
+ PillRemoveButton,
1153
+ {
1154
+ label: removeLabel ?? t.removeNamed(label),
1155
+ onPress: onRemove,
1156
+ color: camInk(theme),
1157
+ disabled
1158
+ }
1159
+ ) : null
1160
+ ]
1161
+ }
1162
+ )
826
1163
  }
827
- ) });
1164
+ );
828
1165
  }
829
1166
  function TrackCountPill({
830
1167
  count,
831
1168
  label,
832
- copy
1169
+ copy,
1170
+ tone = "neutral",
1171
+ size = "md",
1172
+ variant = "glass",
1173
+ leading,
1174
+ loading = false,
1175
+ disabled = false,
1176
+ selected = false,
1177
+ motion,
1178
+ removable = false,
1179
+ onRemove,
1180
+ removeLabel,
1181
+ labels
833
1182
  }) {
834
1183
  const words = useAnalyzerCopy(copy);
1184
+ const t = useViewfinderLabels(labels);
1185
+ const enter = useEnterFade(motion);
1186
+ const theme = useLoamTheme("viewfinder");
835
1187
  const { styles } = useStyles(trackingSheet);
1188
+ const accent = camToneColour(theme, tone);
836
1189
  if (count <= 0) return null;
837
- return /* @__PURE__ */ jsx(
838
- View,
1190
+ const text = label ?? trackCountLabel(count, words);
1191
+ return /* @__PURE__ */ jsxs(
1192
+ Animated.View,
839
1193
  {
840
1194
  accessible: false,
841
1195
  testID: "loam-track-count",
842
- style: styles.countPill,
843
- ...decorativeProps(),
844
- children: /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.countText, children: label ?? trackCountLabel(count, words) })
1196
+ "aria-current": selected ? true : void 0,
1197
+ style: [
1198
+ styles.countPill,
1199
+ size === "sm" ? { paddingHorizontal: theme.space[8], paddingVertical: theme.space[2] } : null,
1200
+ variant === "outline" ? { backgroundColor: "transparent" } : null,
1201
+ accent ? { borderColor: accent } : null,
1202
+ selected ? { backgroundColor: theme.white.a5, borderColor: theme.media.ink } : null,
1203
+ motion === void 0 ? null : { opacity: enter },
1204
+ busyStyle(theme, loading),
1205
+ disabledStyle(theme, disabled)
1206
+ ],
1207
+ ...removable ? {} : decorativeProps(),
1208
+ ...busyProps(loading),
1209
+ ...disabledProps(disabled),
1210
+ children: [
1211
+ loading ? /* @__PURE__ */ jsx(BusySpinner, { color: camInk(theme) }) : leading ? /* @__PURE__ */ jsx(Icon, { name: leading, size: theme.icon.xs, color: camInk(theme) }) : null,
1212
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.countText, children: text }),
1213
+ removable ? /* @__PURE__ */ jsx(PillRemoveButton, { label: removeLabel ?? t.removeNamed(text), onPress: onRemove, color: camInk(theme), disabled }) : null
1214
+ ]
845
1215
  }
846
1216
  );
847
1217
  }
@@ -861,7 +1231,8 @@ function TrackedBox({
861
1231
  chip = true,
862
1232
  chipIndex = 0,
863
1233
  ease = TRACKING_MOTION.ease,
864
- frozen = false
1234
+ frozen = false,
1235
+ loading = false
865
1236
  }) {
866
1237
  const theme = useLoamTheme("viewfinder");
867
1238
  const reduced = useReducedMotion();
@@ -949,9 +1320,11 @@ function TrackedBox({
949
1320
  testID: `loam-track-box-${object.id}`,
950
1321
  style: [
951
1322
  styles.box,
952
- { left: pct(geo.x), top: pct(geo.y), width: pct(geo.w), height: pct(geo.h) }
1323
+ { left: pct(geo.x), top: pct(geo.y), width: pct(geo.w), height: pct(geo.h) },
1324
+ busyStyle(theme, loading)
953
1325
  ],
954
1326
  ...decorativeProps(),
1327
+ ...busyProps(loading),
955
1328
  children: [
956
1329
  /* @__PURE__ */ jsxs(Animated.View, { style: [styles.bracketLayer, { transform: [{ scale: lockScale }] }], children: [
957
1330
  /* @__PURE__ */ jsx(View, { style: [styles.armTopStart, { borderColor: stroke }] }),
@@ -1009,10 +1382,12 @@ function TrackingOverlay({
1009
1382
  dimmed = false,
1010
1383
  safeAreaBottom = 0,
1011
1384
  label,
1012
- copy
1385
+ copy,
1386
+ tone,
1387
+ loading = false
1013
1388
  }) {
1014
1389
  const words = useAnalyzerCopy(copy);
1015
- const { styles } = useStyles(trackingSheet, { dimmed });
1390
+ const { styles } = useStyles(trackingSheet, { dimmed: dimmed || loading });
1016
1391
  const [framePx, setFramePx] = React3.useState(0);
1017
1392
  const { chips, overflow } = visibleChips([...objects], maxChips, framePx || void 0);
1018
1393
  const chipIndex = new Map(chips.map((o, i) => [o.id, i]));
@@ -1027,11 +1402,13 @@ function TrackingOverlay({
1027
1402
  style: styles.overlayRoot,
1028
1403
  onLayout: (e) => setFramePx(e.nativeEvent.layout.width),
1029
1404
  ...name === null ? decorativeProps() : {},
1405
+ ...busyProps(loading),
1030
1406
  children: [
1031
1407
  objects.map((o) => /* @__PURE__ */ jsx(
1032
1408
  TrackedBox,
1033
1409
  {
1034
1410
  object: o,
1411
+ tone,
1035
1412
  chip: chipIndex.has(o.id),
1036
1413
  chipIndex: chipIndex.get(o.id) ?? 0,
1037
1414
  ease,
@@ -1255,6 +1632,423 @@ var trackingSheet = createStyleSheet((theme) => ({
1255
1632
  fontVariant: ["tabular-nums"]
1256
1633
  }
1257
1634
  }));
1635
+ function ObjectHighlight({
1636
+ target,
1637
+ phase,
1638
+ locked = true,
1639
+ highContrast = false,
1640
+ tone = "neutral",
1641
+ loading = false
1642
+ }) {
1643
+ const theme = useLoamTheme("viewfinder");
1644
+ const { styles } = useStyles(identifySheet);
1645
+ const [size, setSize] = React3.useState({ w: 0, h: 0 });
1646
+ const onLayout = React3.useCallback((e) => {
1647
+ const { width: width2, height } = e.nativeEvent.layout;
1648
+ setSize((s) => s.w === width2 && s.h === height ? s : { w: width2, h: height });
1649
+ }, []);
1650
+ if (!target) return null;
1651
+ const weight = highlightWeight(phase, { lost: !locked, highContrast });
1652
+ const width = {
1653
+ "space-3": theme.space[3],
1654
+ "space-4": theme.space[4],
1655
+ "space-6": theme.space[6],
1656
+ "space-8": theme.space[8],
1657
+ thick: theme.borderWidth.thick,
1658
+ heavy: theme.borderWidth.heavy
1659
+ };
1660
+ const black = {
1661
+ 7: theme.black.a7,
1662
+ 8: theme.black.a8,
1663
+ 10: theme.black.a10,
1664
+ 11: theme.black.a11,
1665
+ 12: theme.black.a12,
1666
+ 13: theme.black.a13,
1667
+ 14: theme.black.a14
1668
+ };
1669
+ const { w, h } = size;
1670
+ const d = w > 0 && h > 0 ? target.contour ? contourPath(target.contour, w, h) : boxPath(target.box, w, h, theme.radius.sm) : "";
1671
+ const dash = weight.dashed ? [theme.space[6], theme.space[6]] : void 0;
1672
+ return /* @__PURE__ */ jsxs(
1673
+ View,
1674
+ {
1675
+ style: [styles.root, busyStyle(theme, loading)],
1676
+ onLayout,
1677
+ testID: "loam-object-highlight",
1678
+ ...decorativeProps(),
1679
+ ...busyProps(loading),
1680
+ children: [
1681
+ loading ? /* @__PURE__ */ jsx(View, { style: styles.busyCentre, children: /* @__PURE__ */ jsx(BusySpinner, { color: camToneColour(theme, tone) ?? theme.media.ink }) }) : null,
1682
+ d ? /* @__PURE__ */ jsxs(Svg2, { width: w, height: h, testID: "loam-object-highlight-svg", children: [
1683
+ /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(Mask, { id: "loam-hl-cut", x: "0", y: "0", width: w, height: h, children: [
1684
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: w, height: h, fill: theme.media.ink }),
1685
+ /* @__PURE__ */ jsx(Path, { d, fill: theme.black.a14 })
1686
+ ] }) }),
1687
+ weight.scrim ? /* @__PURE__ */ jsx(
1688
+ Rect,
1689
+ {
1690
+ x: "0",
1691
+ y: "0",
1692
+ width: w,
1693
+ height: h,
1694
+ fill: black[weight.scrim],
1695
+ mask: "url(#loam-hl-cut)"
1696
+ }
1697
+ ) : null,
1698
+ /* @__PURE__ */ jsx(
1699
+ Path,
1700
+ {
1701
+ d,
1702
+ fill: "none",
1703
+ stroke: black[weight.halo.alpha],
1704
+ strokeWidth: width[weight.halo.width],
1705
+ strokeLinejoin: "round",
1706
+ strokeDasharray: dash
1707
+ }
1708
+ ),
1709
+ /* @__PURE__ */ jsx(
1710
+ Path,
1711
+ {
1712
+ d,
1713
+ fill: "none",
1714
+ stroke: camToneColour(theme, tone) ?? (weight.ink.alpha ? theme.white.a12 : theme.media.ink),
1715
+ strokeWidth: width[weight.ink.width],
1716
+ strokeLinejoin: "round",
1717
+ strokeDasharray: dash
1718
+ }
1719
+ )
1720
+ ] }) : null
1721
+ ]
1722
+ }
1723
+ );
1724
+ }
1725
+ function ObjectLabel({
1726
+ name,
1727
+ conf = 0,
1728
+ state = "identified",
1729
+ box,
1730
+ onOpen,
1731
+ labels,
1732
+ tone: toneProp
1733
+ }) {
1734
+ const theme = useLoamTheme("viewfinder");
1735
+ const t = useViewfinderLabels(labels);
1736
+ const { styles } = useStyles(identifySheet);
1737
+ const tone = toneProp ?? (state === "identified" ? confidenceTone(conf) : "neutral");
1738
+ const pct2 = confidenceLabel(conf);
1739
+ const text = state === "identifying" ? t.identifying : state === "lost" ? t.holdSteady : name;
1740
+ const dot = camToneColour(theme, tone) ?? theme.white.a12;
1741
+ const slot = box ? chipSlot(box) : "above";
1742
+ const [w, setW] = React3.useState(0);
1743
+ const pin = box ? {
1744
+ position: "absolute",
1745
+ left: `${box[0] + box[2] / 2}%`,
1746
+ top: `${slot === "below" ? box[1] + box[3] : box[1]}%`,
1747
+ transform: [
1748
+ { translateX: -w / 2 },
1749
+ { translateY: slot === "above" ? -(theme.ctl.sm + theme.space[4]) : theme.space[4] }
1750
+ ],
1751
+ alignItems: "center"
1752
+ } : null;
1753
+ const pill = /* @__PURE__ */ jsxs(
1754
+ View,
1755
+ {
1756
+ style: styles.label,
1757
+ testID: `loam-object-label-${state}`,
1758
+ onLayout: (e) => setW(e.nativeEvent.layout.width),
1759
+ children: [
1760
+ state === "lost" ? null : /* @__PURE__ */ jsx(View, { style: [styles.dot, { backgroundColor: dot }] }),
1761
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.labelText, children: text }),
1762
+ state === "identified" ? /* @__PURE__ */ jsx(Text, { style: styles.labelConf, children: pct2 }) : null
1763
+ ]
1764
+ }
1765
+ );
1766
+ if (state !== "identified") {
1767
+ return /* @__PURE__ */ jsx(View, { style: pin, pointerEvents: "none", ...decorativeProps(), children: pill });
1768
+ }
1769
+ return /* @__PURE__ */ jsx(
1770
+ Pressable,
1771
+ {
1772
+ accessibilityRole: "button",
1773
+ accessibilityLabel: t.openResult(name, pct2),
1774
+ hitSlop: Math.max(0, (theme.hit.lg - theme.ctl.sm) / 2),
1775
+ onPress: onOpen,
1776
+ style: pin ?? void 0,
1777
+ children: pill
1778
+ }
1779
+ );
1780
+ }
1781
+ function IdentifyCard({
1782
+ name,
1783
+ sub,
1784
+ conf,
1785
+ thumb,
1786
+ platform = "ios",
1787
+ onOpen,
1788
+ labels,
1789
+ loading = false,
1790
+ tone = "neutral",
1791
+ variant = "glass",
1792
+ elevation = "flat",
1793
+ padding = "md"
1794
+ }) {
1795
+ const theme = useLoamTheme("viewfinder");
1796
+ const t = useViewfinderLabels(labels);
1797
+ const { styles } = useStyles(identifySheet, { platform });
1798
+ const pct2 = confidenceLabel(conf);
1799
+ return /* @__PURE__ */ jsxs(
1800
+ Pressable,
1801
+ {
1802
+ accessibilityRole: "button",
1803
+ accessibilityLabel: t.openResult(name, pct2),
1804
+ onPress: loading ? void 0 : onOpen,
1805
+ accessibilityState: loading ? { busy: true } : void 0,
1806
+ testID: `loam-identify-card-${platform}`,
1807
+ style: [
1808
+ styles.card,
1809
+ { paddingHorizontal: theme.space[padding === "sm" ? 8 : padding === "lg" ? 16 : 12] },
1810
+ variant === "solid" ? { backgroundColor: theme.media.ink, borderColor: theme.media.ink } : null,
1811
+ camToneEdge(theme, tone),
1812
+ variant === "outline" ? { backgroundColor: "transparent" } : null,
1813
+ elevation === "default" ? theme.shadow.sm : elevation === "raised" || variant === "elevated" && elevation === "flat" ? theme.shadow.md : null
1814
+ ],
1815
+ ...busyProps(loading),
1816
+ children: [
1817
+ /* @__PURE__ */ jsx(View, { style: styles.thumb, ...decorativeProps(), children: thumb }),
1818
+ /* @__PURE__ */ jsxs(View, { style: styles.cardText, children: [
1819
+ /* @__PURE__ */ jsx(
1820
+ Text,
1821
+ {
1822
+ numberOfLines: 1,
1823
+ style: [styles.cardName, variant === "solid" ? { color: theme.media.onInk } : null],
1824
+ children: name
1825
+ }
1826
+ ),
1827
+ sub ? /* @__PURE__ */ jsx(
1828
+ Text,
1829
+ {
1830
+ numberOfLines: 1,
1831
+ style: [styles.cardSub, variant === "solid" ? { color: theme.media.onInk } : null],
1832
+ children: sub
1833
+ }
1834
+ ) : null
1835
+ ] }),
1836
+ /* @__PURE__ */ jsx(View, { ...decorativeProps(), children: loading ? /* @__PURE__ */ jsx(BusySpinner, { color: variant === "solid" ? theme.media.onInk : camInk(theme) }) : /* @__PURE__ */ jsx(Badge, { variant: confidenceTone(conf), size: "sm", children: pct2 }) }),
1837
+ /* @__PURE__ */ jsx(
1838
+ Icon,
1839
+ {
1840
+ name: "chevron-up",
1841
+ size: theme.icon.md,
1842
+ color: variant === "solid" ? theme.media.onInk : camInk(theme)
1843
+ }
1844
+ )
1845
+ ]
1846
+ }
1847
+ );
1848
+ }
1849
+ var identifySheet = createStyleSheet((theme) => ({
1850
+ root: {
1851
+ pointerEvents: "none",
1852
+ position: "absolute",
1853
+ top: theme.space[0],
1854
+ bottom: theme.space[0],
1855
+ left: theme.space[0],
1856
+ right: theme.space[0]
1857
+ },
1858
+ busyCentre: {
1859
+ pointerEvents: "none",
1860
+ position: "absolute",
1861
+ top: theme.space[0],
1862
+ bottom: theme.space[0],
1863
+ left: theme.space[0],
1864
+ right: theme.space[0],
1865
+ alignItems: "center",
1866
+ justifyContent: "center"
1867
+ },
1868
+ label: {
1869
+ flexDirection: "row",
1870
+ alignItems: "center",
1871
+ gap: theme.space[8],
1872
+ height: theme.ctl.sm,
1873
+ paddingHorizontal: theme.space[12],
1874
+ borderRadius: theme.radius.full,
1875
+ backgroundColor: theme.black.a13,
1876
+ borderWidth: theme.borderWidth.base,
1877
+ borderColor: theme.white.a5
1878
+ },
1879
+ dot: {
1880
+ width: theme.space[8],
1881
+ height: theme.space[8],
1882
+ borderRadius: theme.radius.full
1883
+ },
1884
+ labelText: {
1885
+ fontFamily: theme.font.sans,
1886
+ fontSize: theme.fontSize[13],
1887
+ fontWeight: theme.fontWeight.semibold,
1888
+ color: camInk(theme),
1889
+ flexShrink: 1
1890
+ },
1891
+ labelConf: {
1892
+ fontFamily: theme.font.sans,
1893
+ fontSize: theme.fontSize[13],
1894
+ color: theme.white.a14
1895
+ },
1896
+ card: {
1897
+ flexDirection: "row",
1898
+ alignItems: "center",
1899
+ gap: theme.space[12],
1900
+ paddingHorizontal: theme.space[12],
1901
+ backgroundColor: theme.black.a13,
1902
+ borderWidth: theme.borderWidth.base,
1903
+ borderColor: theme.white.a5,
1904
+ variants: {
1905
+ platform: {
1906
+ ios: { height: theme.space[64], borderRadius: theme.radius.lg },
1907
+ android: { height: theme.space[72], borderRadius: theme.space[20] }
1908
+ }
1909
+ }
1910
+ },
1911
+ thumb: {
1912
+ overflow: "hidden",
1913
+ alignItems: "center",
1914
+ justifyContent: "center",
1915
+ variants: {
1916
+ platform: {
1917
+ ios: { width: theme.space[44], height: theme.space[44], borderRadius: theme.space[10] },
1918
+ android: { width: theme.space[48], height: theme.space[48], borderRadius: theme.radius.md }
1919
+ }
1920
+ }
1921
+ },
1922
+ cardText: {
1923
+ flexGrow: 1,
1924
+ flexShrink: 1,
1925
+ minWidth: theme.space[0],
1926
+ gap: theme.space[2]
1927
+ },
1928
+ cardName: {
1929
+ fontFamily: theme.font.sans,
1930
+ fontSize: theme.fontSize[14],
1931
+ fontWeight: theme.fontWeight.semibold,
1932
+ color: camInk(theme)
1933
+ },
1934
+ cardSub: {
1935
+ fontFamily: theme.font.sans,
1936
+ fontSize: theme.fontSize[12],
1937
+ color: theme.white.a14
1938
+ }
1939
+ }));
1940
+ function ViewfinderModes({
1941
+ modes,
1942
+ value,
1943
+ onChange,
1944
+ platform,
1945
+ label = "Mode",
1946
+ testID,
1947
+ tone = "neutral",
1948
+ loading = false,
1949
+ disabled = false,
1950
+ size = "md",
1951
+ variant,
1952
+ orientation = "horizontal",
1953
+ fullWidth = false,
1954
+ density = "comfortable"
1955
+ }) {
1956
+ const theme = useLoamTheme("viewfinder");
1957
+ const accent = camToneColour(theme, tone);
1958
+ const blocked = disabled || loading;
1959
+ const chipHeight = size === "sm" ? theme.space[24] : size === "lg" ? theme.ctl.lg : theme.space[32];
1960
+ const { styles } = useStyles(modesSheet);
1961
+ const which = platform ?? (isAndroidIdiom(theme) ? "android" : "ios");
1962
+ const strip = variant ?? (which === "android" ? "glass" : "text");
1963
+ const chips = strip !== "text";
1964
+ return /* @__PURE__ */ jsx(
1965
+ View,
1966
+ {
1967
+ accessibilityRole: "radiogroup",
1968
+ accessibilityLabel: label,
1969
+ testID,
1970
+ style: [
1971
+ styles.row,
1972
+ chips ? styles.capsule : styles.strip,
1973
+ chips && strip === "glass" ? camGlass(theme) : null,
1974
+ chips && strip === "plain" ? { borderColor: "transparent" } : null,
1975
+ orientation === "vertical" ? { flexDirection: "column" } : null,
1976
+ density === "compact" ? { gap: chips ? theme.space[0] : theme.space[12] } : null,
1977
+ fullWidth ? { alignSelf: "stretch", justifyContent: "space-around" } : null,
1978
+ disabled ? { opacity: theme.state.disabledOpacity } : busyStyle(theme, loading)
1979
+ ],
1980
+ ...busyProps(loading),
1981
+ children: modes.map((m) => {
1982
+ const on = m.id === value;
1983
+ return /* @__PURE__ */ jsx(
1984
+ Pressable,
1985
+ {
1986
+ accessibilityRole: "radio",
1987
+ accessibilityLabel: m.label,
1988
+ accessibilityState: {
1989
+ checked: on,
1990
+ ...disabled ? { disabled: true } : null,
1991
+ ...loading ? { busy: true } : null
1992
+ },
1993
+ disabled: blocked,
1994
+ onPress: () => onChange?.(m.id),
1995
+ hitSlop: Math.max(0, (theme.hit.lg - (chips ? theme.ctl.sm + 2 : 24)) / 2),
1996
+ style: [
1997
+ chips ? styles.chip : styles.word,
1998
+ chips ? { height: chipHeight } : null,
1999
+ chips && on ? styles.chipOn : null,
2000
+ chips && on && accent ? { backgroundColor: accent } : null
2001
+ ],
2002
+ "aria-checked": on,
2003
+ children: /* @__PURE__ */ jsx(
2004
+ Text,
2005
+ {
2006
+ style: chips ? [styles.chipText, on ? styles.chipTextOn : styles.chipTextRest] : [
2007
+ styles.wordText,
2008
+ on ? styles.wordTextOn : styles.wordTextRest,
2009
+ on && accent ? { color: accent } : null
2010
+ ],
2011
+ children: chips ? m.label : m.label.toUpperCase()
2012
+ }
2013
+ )
2014
+ },
2015
+ m.id
2016
+ );
2017
+ })
2018
+ }
2019
+ );
2020
+ }
2021
+ var modesSheet = createStyleSheet((theme) => ({
2022
+ row: { flexDirection: "row", alignItems: "center", justifyContent: "center" },
2023
+ strip: { gap: theme.space[22] },
2024
+ capsule: {
2025
+ alignSelf: "center",
2026
+ gap: theme.space[2],
2027
+ padding: theme.space[2],
2028
+ borderRadius: theme.radius.full,
2029
+ borderWidth: theme.borderWidth.base,
2030
+ borderColor: theme.white.a5
2031
+ },
2032
+ word: { minHeight: theme.space[24], justifyContent: "center" },
2033
+ wordText: {
2034
+ fontFamily: theme.font.sans,
2035
+ fontSize: theme.fontSize[12],
2036
+ fontWeight: theme.fontWeight.bold,
2037
+ letterSpacing: theme.tracking.wider * theme.fontSize[12]
2038
+ },
2039
+ wordTextOn: { color: theme.media.ink },
2040
+ wordTextRest: { color: theme.white.a13 },
2041
+ chip: {
2042
+ height: theme.space[32],
2043
+ paddingHorizontal: theme.space[14],
2044
+ borderRadius: theme.radius.full,
2045
+ justifyContent: "center"
2046
+ },
2047
+ chipOn: { backgroundColor: theme.media.ink },
2048
+ chipText: { fontFamily: theme.font.sans, fontSize: theme.fontSize[14] },
2049
+ chipTextOn: { color: theme.media.onInk, fontWeight: theme.fontWeight.semibold },
2050
+ chipTextRest: { color: theme.media.ink, fontWeight: theme.fontWeight.medium }
2051
+ }));
1258
2052
  function SequenceStrip({
1259
2053
  total = 6,
1260
2054
  shots = 0,
@@ -1265,7 +2059,9 @@ function SequenceStrip({
1265
2059
  labels,
1266
2060
  copy,
1267
2061
  onRedo,
1268
- onRead
2062
+ onRead,
2063
+ loading = false,
2064
+ tone = "neutral"
1269
2065
  }) {
1270
2066
  const t = useViewfinderLabels(labels);
1271
2067
  const words = useAnalyzerCopy(copy);
@@ -1279,7 +2075,9 @@ function SequenceStrip({
1279
2075
  {
1280
2076
  role: "group",
1281
2077
  accessibilityLabel: batch ? t.capturedPages : t.captureSequence,
1282
- style: styles.strip,
2078
+ style: [styles.strip, camToneEdge(theme, tone), busyStyle(theme, loading)],
2079
+ pointerEvents: loading ? "none" : void 0,
2080
+ ...busyProps(loading),
1283
2081
  children: [
1284
2082
  /* @__PURE__ */ jsx(
1285
2083
  ScrollView,
@@ -1300,7 +2098,7 @@ function SequenceStrip({
1300
2098
  accessibilityRole: "button",
1301
2099
  accessibilityLabel: label,
1302
2100
  style: styles.cellDone,
1303
- hitSlop: (theme.hit.lg - theme.space[32]) / 2,
2101
+ hitSlop: (theme.hit.lg - theme.ctl.sm) / 2,
1304
2102
  onPress: () => onRedo?.(i),
1305
2103
  children: /* @__PURE__ */ jsx(
1306
2104
  Icon,
@@ -1336,7 +2134,7 @@ function SequenceStrip({
1336
2134
  {
1337
2135
  accessibilityRole: "button",
1338
2136
  style: styles.pinned,
1339
- hitSlop: (theme.hit.lg - theme.space[32]) / 2,
2137
+ hitSlop: (theme.hit.lg - theme.ctl.sm) / 2,
1340
2138
  onPress: onRead,
1341
2139
  children: /* @__PURE__ */ jsx(Text, { style: styles.pinnedLabel, children: readLabel ?? readBatchLabel(shots, words) })
1342
2140
  }
@@ -1382,6 +2180,7 @@ function Stop2({
1382
2180
  accessibilityLabel: label,
1383
2181
  accessibilityState: { selected: on },
1384
2182
  style: styles.stop,
2183
+ hitSlop: Math.max(0, (theme.hit.lg - theme.ctl.md) / 2),
1385
2184
  onPress: onPick,
1386
2185
  ...pressedProps(on),
1387
2186
  children: /* @__PURE__ */ jsx(Text, { style: [styles.stopLabel, { color: on ? theme.media.onInk : camInk(theme) }], children: label })
@@ -1394,7 +2193,9 @@ function ExpertPanel({
1394
2193
  labels,
1395
2194
  copy,
1396
2195
  onChange,
1397
- onClose
2196
+ onClose,
2197
+ loading = false,
2198
+ tone = "neutral"
1398
2199
  }) {
1399
2200
  const t = useViewfinderLabels(labels);
1400
2201
  const words = useAnalyzerCopy(copy);
@@ -1417,74 +2218,84 @@ function ExpertPanel({
1417
2218
  [t.level, level, "level"],
1418
2219
  [t.grid, grid, "grid"]
1419
2220
  ];
1420
- return /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: t.expertControls, style: styles.panel, children: [
1421
- /* @__PURE__ */ jsxs(View, { style: styles.panelHead, children: [
1422
- /* @__PURE__ */ jsx(Text, { style: [styles.panelTitle, { color: camInk(theme) }], children: t.expert }),
1423
- /* @__PURE__ */ jsx(View, { style: styles.panelHeadEnd, children: onClose ? /* @__PURE__ */ jsx(GlassIconButton, { icon: "x", label: t.closeExpert, onPress: onClose }) : null })
1424
- ] }),
1425
- /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.ev, style: styles.group, children: [
1426
- /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.ev.toLocaleUpperCase(locale) }),
1427
- /* @__PURE__ */ jsx(
1428
- ScrollView,
1429
- {
1430
- horizontal: true,
1431
- showsHorizontalScrollIndicator: false,
1432
- contentContainerStyle: styles.stopRow,
1433
- children: EV_STOPS.map((stop) => /* @__PURE__ */ jsx(
2221
+ return /* @__PURE__ */ jsxs(
2222
+ View,
2223
+ {
2224
+ role: "group",
2225
+ accessibilityLabel: t.expertControls,
2226
+ style: [styles.panel, camToneEdge(theme, tone), busyStyle(theme, loading)],
2227
+ pointerEvents: loading ? "none" : void 0,
2228
+ ...busyProps(loading),
2229
+ children: [
2230
+ /* @__PURE__ */ jsxs(View, { style: styles.panelHead, children: [
2231
+ /* @__PURE__ */ jsx(Text, { style: [styles.panelTitle, { color: camInk(theme) }], children: t.expert }),
2232
+ /* @__PURE__ */ jsx(View, { style: styles.panelHeadEnd, children: onClose ? /* @__PURE__ */ jsx(GlassIconButton, { icon: "x", label: t.closeExpert, onPress: onClose }) : null })
2233
+ ] }),
2234
+ /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.ev, style: styles.group, children: [
2235
+ /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.ev.toLocaleUpperCase(locale) }),
2236
+ /* @__PURE__ */ jsx(
2237
+ ScrollView,
2238
+ {
2239
+ horizontal: true,
2240
+ showsHorizontalScrollIndicator: false,
2241
+ contentContainerStyle: styles.stopRow,
2242
+ children: EV_STOPS.map((stop) => /* @__PURE__ */ jsx(
2243
+ Stop2,
2244
+ {
2245
+ on: stop === ev,
2246
+ label: evLabel(stop, locale),
2247
+ onPick: () => onChange?.({ control: "ev", value: stop })
2248
+ },
2249
+ stop
2250
+ ))
2251
+ }
2252
+ )
2253
+ ] }),
2254
+ /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.torch, style: styles.group, children: [
2255
+ /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.torch.toLocaleUpperCase(locale) }),
2256
+ /* @__PURE__ */ jsx(View, { style: styles.stopRow, children: ["off", "low", "high"].map((lvl) => /* @__PURE__ */ jsx(
1434
2257
  Stop2,
1435
2258
  {
1436
- on: stop === ev,
1437
- label: evLabel(stop, locale),
1438
- onPick: () => onChange?.({ control: "ev", value: stop })
2259
+ on: lvl === torch,
2260
+ label: t.torchLevels[lvl],
2261
+ onPick: () => onChange?.({ control: "torch", value: lvl })
1439
2262
  },
1440
- stop
1441
- ))
1442
- }
1443
- )
1444
- ] }),
1445
- /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.torch, style: styles.group, children: [
1446
- /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.torch.toLocaleUpperCase(locale) }),
1447
- /* @__PURE__ */ jsx(View, { style: styles.stopRow, children: ["off", "low", "high"].map((lvl) => /* @__PURE__ */ jsx(
1448
- Stop2,
1449
- {
1450
- on: lvl === torch,
1451
- label: t.torchLevels[lvl],
1452
- onPick: () => onChange?.({ control: "torch", value: lvl })
1453
- },
1454
- lvl
1455
- )) })
1456
- ] }),
1457
- /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.format, style: styles.group, children: [
1458
- /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.format.toLocaleUpperCase(locale) }),
1459
- /* @__PURE__ */ jsx(View, { style: styles.stopRow, children: ["pipeline", "full"].map((f) => /* @__PURE__ */ jsx(
1460
- Stop2,
1461
- {
1462
- on: f === format,
1463
- label: t.formats[f],
1464
- onPick: () => onChange?.({ control: "format", value: f })
1465
- },
1466
- f
1467
- )) })
1468
- ] }),
1469
- /* @__PURE__ */ jsx(
1470
- View,
1471
- {
1472
- role: "group",
1473
- accessibilityLabel: GROUP.gridLevel,
1474
- style: styles.toggleRow,
1475
- testID: `loam-expert-${platform}`,
1476
- children: toggles.map(([label, on, control]) => /* @__PURE__ */ jsx(
1477
- Stop2,
2263
+ lvl
2264
+ )) })
2265
+ ] }),
2266
+ /* @__PURE__ */ jsxs(View, { role: "group", accessibilityLabel: GROUP.format, style: styles.group, children: [
2267
+ /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, camMeta(theme)], children: GROUP.format.toLocaleUpperCase(locale) }),
2268
+ /* @__PURE__ */ jsx(View, { style: styles.stopRow, children: ["pipeline", "full"].map((f) => /* @__PURE__ */ jsx(
2269
+ Stop2,
2270
+ {
2271
+ on: f === format,
2272
+ label: t.formats[f],
2273
+ onPick: () => onChange?.({ control: "format", value: f })
2274
+ },
2275
+ f
2276
+ )) })
2277
+ ] }),
2278
+ /* @__PURE__ */ jsx(
2279
+ View,
1478
2280
  {
1479
- on,
1480
- label,
1481
- onPick: () => onChange?.({ control, value: !on })
1482
- },
1483
- control
1484
- ))
1485
- }
1486
- )
1487
- ] });
2281
+ role: "group",
2282
+ accessibilityLabel: GROUP.gridLevel,
2283
+ style: styles.toggleRow,
2284
+ testID: `loam-expert-${platform}`,
2285
+ children: toggles.map(([label, on, control]) => /* @__PURE__ */ jsx(
2286
+ Stop2,
2287
+ {
2288
+ on,
2289
+ label,
2290
+ onPick: () => onChange?.({ control, value: !on })
2291
+ },
2292
+ control
2293
+ ))
2294
+ }
2295
+ )
2296
+ ]
2297
+ }
2298
+ );
1488
2299
  }
1489
2300
  var sequenceSheet = createStyleSheet((theme) => ({
1490
2301
  strip: {
@@ -1503,8 +2314,8 @@ var sequenceSheet = createStyleSheet((theme) => ({
1503
2314
  gap: theme.space[6]
1504
2315
  },
1505
2316
  cellDone: {
1506
- width: theme.space[32],
1507
- height: theme.space[32],
2317
+ width: theme.ctl.sm,
2318
+ height: theme.ctl.sm,
1508
2319
  flexGrow: 0,
1509
2320
  flexShrink: 0,
1510
2321
  alignItems: "center",
@@ -1515,8 +2326,8 @@ var sequenceSheet = createStyleSheet((theme) => ({
1515
2326
  borderColor: theme.white.a5
1516
2327
  },
1517
2328
  cellPending: {
1518
- width: theme.space[32],
1519
- height: theme.space[32],
2329
+ width: theme.ctl.sm,
2330
+ height: theme.ctl.sm,
1520
2331
  flexGrow: 0,
1521
2332
  flexShrink: 0,
1522
2333
  alignItems: "center",
@@ -1539,7 +2350,7 @@ var sequenceSheet = createStyleSheet((theme) => ({
1539
2350
  pinned: {
1540
2351
  flexGrow: 0,
1541
2352
  flexShrink: 0,
1542
- height: theme.space[32],
2353
+ height: theme.ctl.sm,
1543
2354
  alignItems: "center",
1544
2355
  justifyContent: "center",
1545
2356
  paddingHorizontal: theme.space[12],
@@ -1548,15 +2359,15 @@ var sequenceSheet = createStyleSheet((theme) => ({
1548
2359
  },
1549
2360
  pinnedLabel: {
1550
2361
  fontFamily: theme.font.sans,
1551
- fontSize: theme.fontSize[12],
1552
- fontWeight: theme.fontWeight.medium,
2362
+ fontSize: theme.fontSize[13],
2363
+ fontWeight: theme.fontWeight.semibold,
1553
2364
  color: theme.media.onInk
1554
2365
  },
1555
2366
  panel: {
1556
2367
  flexDirection: "column",
1557
2368
  gap: theme.space[16],
1558
2369
  padding: theme.space[16],
1559
- borderRadius: theme.radius.md,
2370
+ borderRadius: theme.radius.lg,
1560
2371
  backgroundColor: theme.black.a12,
1561
2372
  borderWidth: theme.borderWidth.base,
1562
2373
  borderColor: theme.white.a5
@@ -1578,7 +2389,8 @@ var sequenceSheet = createStyleSheet((theme) => ({
1578
2389
  gap: theme.space[8]
1579
2390
  },
1580
2391
  groupLabel: {
1581
- fontSize: theme.fontSize[10]
2392
+ fontSize: theme.fontSize[11],
2393
+ fontWeight: theme.fontWeight.bold
1582
2394
  },
1583
2395
  stopRow: {
1584
2396
  flexDirection: "row",
@@ -1592,8 +2404,8 @@ var sequenceSheet = createStyleSheet((theme) => ({
1592
2404
  gap: theme.space[8]
1593
2405
  },
1594
2406
  stop: {
1595
- height: theme.ctl.lg,
1596
- minWidth: theme.ctl.lg,
2407
+ height: theme.ctl.md,
2408
+ minWidth: theme.ctl.md,
1597
2409
  flexGrow: 0,
1598
2410
  flexShrink: 0,
1599
2411
  alignItems: "center",
@@ -1611,7 +2423,8 @@ var sequenceSheet = createStyleSheet((theme) => ({
1611
2423
  },
1612
2424
  stopLabel: {
1613
2425
  fontFamily: theme.font.sans,
1614
- fontSize: theme.fontSize[11],
2426
+ fontSize: theme.fontSize[14],
2427
+ fontWeight: theme.fontWeight.semibold,
1615
2428
  fontVariant: ["tabular-nums"]
1616
2429
  }
1617
2430
  }));
@@ -1620,18 +2433,47 @@ function ShutterTray({
1620
2433
  start,
1621
2434
  primary,
1622
2435
  end,
1623
- stack = false
2436
+ stack = false,
2437
+ size = "md",
2438
+ density = "comfortable",
2439
+ orientation = "horizontal",
2440
+ variant = "plain",
2441
+ tone = "neutral",
2442
+ loading = false
1624
2443
  }) {
1625
2444
  const { styles } = useStyles(traySheet);
2445
+ const theme = useLoamTheme("viewfinder");
2446
+ const accent = camToneColour(theme, tone);
2447
+ const slot = {
2448
+ width: size === "sm" ? theme.ctl.md : size === "lg" ? theme.space[48] : theme.space[44]
2449
+ };
2450
+ const chrome = [
2451
+ variant === "glass" ? [camGlass(theme), { borderRadius: theme.radius.lg }] : null,
2452
+ accent ? { borderWidth: theme.borderWidth.base, borderColor: accent } : null,
2453
+ density === "compact" ? { gap: theme.space[8], paddingHorizontal: theme.space[8] } : null,
2454
+ busyStyle(theme, loading)
2455
+ ];
1626
2456
  const secondaries = /* @__PURE__ */ jsxs(Fragment, { children: [
1627
- /* @__PURE__ */ jsx(View, { style: styles.slotStart, children: start }),
2457
+ /* @__PURE__ */ jsx(View, { style: [styles.slotStart, slot], children: start }),
1628
2458
  /* @__PURE__ */ jsx(View, { style: styles.slotPrimary, children: stack ? null : primary }),
1629
- /* @__PURE__ */ jsx(View, { style: styles.slotEnd, children: end })
2459
+ /* @__PURE__ */ jsx(View, { style: [styles.slotEnd, slot], children: end })
1630
2460
  ] });
1631
2461
  if (!stack) {
1632
- return /* @__PURE__ */ jsx(View, { style: styles.tray, testID: `loam-tray-${platform}`, children: secondaries });
2462
+ return /* @__PURE__ */ jsx(
2463
+ View,
2464
+ {
2465
+ style: [
2466
+ styles.tray,
2467
+ orientation === "vertical" ? { flexDirection: "column" } : null,
2468
+ chrome
2469
+ ],
2470
+ testID: `loam-tray-${platform}`,
2471
+ ...busyProps(loading),
2472
+ children: secondaries
2473
+ }
2474
+ );
1633
2475
  }
1634
- return /* @__PURE__ */ jsxs(View, { style: styles.stackedTray, testID: `loam-tray-${platform}`, children: [
2476
+ return /* @__PURE__ */ jsxs(View, { style: [styles.stackedTray, chrome], testID: `loam-tray-${platform}`, ...busyProps(loading), children: [
1635
2477
  /* @__PURE__ */ jsx(View, { style: styles.stackedPrimary, children: primary }),
1636
2478
  /* @__PURE__ */ jsx(View, { style: styles.stackedRow, children: secondaries })
1637
2479
  ] });
@@ -1665,7 +2507,7 @@ var traySheet = createStyleSheet((theme) => ({
1665
2507
  gap: theme.space[16]
1666
2508
  },
1667
2509
  slotStart: {
1668
- width: theme.space[48],
2510
+ width: theme.space[44],
1669
2511
  flexGrow: 0,
1670
2512
  flexShrink: 0,
1671
2513
  flexDirection: "row",
@@ -1681,7 +2523,7 @@ var traySheet = createStyleSheet((theme) => ({
1681
2523
  justifyContent: "center"
1682
2524
  },
1683
2525
  slotEnd: {
1684
- width: theme.space[48],
2526
+ width: theme.space[44],
1685
2527
  flexGrow: 0,
1686
2528
  flexShrink: 0,
1687
2529
  flexDirection: "row",
@@ -1690,4 +2532,4 @@ var traySheet = createStyleSheet((theme) => ({
1690
2532
  }
1691
2533
  }));
1692
2534
 
1693
- export { ContinuousNotice, CountdownRing, EV_STOPS, ExpertPanel, FlipButton, FocusIndicator, FocusTapZone, GuideOverlay, LensPicker, ScanLine, SequenceStrip, ShutterButton, ShutterTray, TorchToggle, TrackChip, TrackCountPill, TrackedBox, TrackingOverlay, ViewfinderGridOverlay, ViewfinderGridToggle };
2535
+ export { ContinuousNotice, CountdownRing, EV_STOPS, ExpertPanel, FlipButton, FocusIndicator, FocusTapZone, GuideOverlay, IdentifyCard, LensPicker, ObjectHighlight, ObjectLabel, ScanLine, SequenceStrip, ShutterButton, ShutterTray, TorchToggle, TrackChip, TrackCountPill, TrackedBox, TrackingOverlay, ViewfinderGridOverlay, ViewfinderGridToggle, ViewfinderModes };