designmd-forge 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (907) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -0
  3. package/dist/__tests__/designStore.test.js +41 -0
  4. package/dist/__tests__/linter.test.js +23 -0
  5. package/dist/__tests__/sectionParser.test.js +60 -0
  6. package/dist/__tests__/server.test.js +129 -0
  7. package/dist/constants.js +12 -0
  8. package/dist/data/authoring-guide.md +113 -0
  9. package/dist/data/designs/airbnb.md +545 -0
  10. package/dist/data/designs/airtable.md +554 -0
  11. package/dist/data/designs/apple.md +562 -0
  12. package/dist/data/designs/binance.md +634 -0
  13. package/dist/data/designs/bmw-m.md +503 -0
  14. package/dist/data/designs/bmw.md +544 -0
  15. package/dist/data/designs/bugatti.md +454 -0
  16. package/dist/data/designs/cal.md +542 -0
  17. package/dist/data/designs/card-heavy.md +250 -0
  18. package/dist/data/designs/claude.md +589 -0
  19. package/dist/data/designs/clay.md +541 -0
  20. package/dist/data/designs/clickhouse.md +544 -0
  21. package/dist/data/designs/cohere.md +451 -0
  22. package/dist/data/designs/coinbase.md +570 -0
  23. package/dist/data/designs/composio.md +506 -0
  24. package/dist/data/designs/content-first.md +236 -0
  25. package/dist/data/designs/cursor.md +537 -0
  26. package/dist/data/designs/data-dashboard.md +300 -0
  27. package/dist/data/designs/dell-1996.md +632 -0
  28. package/dist/data/designs/elevenlabs.md +504 -0
  29. package/dist/data/designs/enterprise-neutral.md +252 -0
  30. package/dist/data/designs/expo.md +526 -0
  31. package/dist/data/designs/ferrari.md +531 -0
  32. package/dist/data/designs/figma.md +578 -0
  33. package/dist/data/designs/framer.md +544 -0
  34. package/dist/data/designs/hashicorp.md +575 -0
  35. package/dist/data/designs/hp.md +670 -0
  36. package/dist/data/designs/ibm.md +550 -0
  37. package/dist/data/designs/intercom.md +546 -0
  38. package/dist/data/designs/ios-acorns-android.md +430 -0
  39. package/dist/data/designs/ios-acorns-expo.md +381 -0
  40. package/dist/data/designs/ios-acorns-swiftui.md +378 -0
  41. package/dist/data/designs/ios-acorns.md +384 -0
  42. package/dist/data/designs/ios-airbnb-android.md +658 -0
  43. package/dist/data/designs/ios-airbnb-expo.md +457 -0
  44. package/dist/data/designs/ios-airbnb-swiftui.md +464 -0
  45. package/dist/data/designs/ios-airbnb.md +410 -0
  46. package/dist/data/designs/ios-alltrails-android.md +451 -0
  47. package/dist/data/designs/ios-alltrails-expo.md +400 -0
  48. package/dist/data/designs/ios-alltrails-swiftui.md +343 -0
  49. package/dist/data/designs/ios-alltrails.md +344 -0
  50. package/dist/data/designs/ios-amazon-android.md +686 -0
  51. package/dist/data/designs/ios-amazon-expo.md +433 -0
  52. package/dist/data/designs/ios-amazon-music-android.md +416 -0
  53. package/dist/data/designs/ios-amazon-music-expo.md +368 -0
  54. package/dist/data/designs/ios-amazon-music-swiftui.md +436 -0
  55. package/dist/data/designs/ios-amazon-music.md +389 -0
  56. package/dist/data/designs/ios-amazon-swiftui.md +460 -0
  57. package/dist/data/designs/ios-amazon.md +440 -0
  58. package/dist/data/designs/ios-apple-fitness-android.md +462 -0
  59. package/dist/data/designs/ios-apple-fitness-expo.md +373 -0
  60. package/dist/data/designs/ios-apple-fitness-swiftui.md +373 -0
  61. package/dist/data/designs/ios-apple-fitness.md +399 -0
  62. package/dist/data/designs/ios-apple-maps-android.md +646 -0
  63. package/dist/data/designs/ios-apple-maps-expo.md +557 -0
  64. package/dist/data/designs/ios-apple-maps-swiftui.md +588 -0
  65. package/dist/data/designs/ios-apple-maps.md +447 -0
  66. package/dist/data/designs/ios-apple-music-android.md +737 -0
  67. package/dist/data/designs/ios-apple-music-expo.md +596 -0
  68. package/dist/data/designs/ios-apple-music-swiftui.md +578 -0
  69. package/dist/data/designs/ios-apple-music.md +494 -0
  70. package/dist/data/designs/ios-apple-notes-android.md +675 -0
  71. package/dist/data/designs/ios-apple-notes-expo.md +468 -0
  72. package/dist/data/designs/ios-apple-notes-swiftui.md +489 -0
  73. package/dist/data/designs/ios-apple-notes.md +413 -0
  74. package/dist/data/designs/ios-apple-tv-android.md +405 -0
  75. package/dist/data/designs/ios-apple-tv-expo.md +341 -0
  76. package/dist/data/designs/ios-apple-tv-swiftui.md +348 -0
  77. package/dist/data/designs/ios-apple-tv.md +390 -0
  78. package/dist/data/designs/ios-apple-wallet-android.md +617 -0
  79. package/dist/data/designs/ios-apple-wallet-expo.md +487 -0
  80. package/dist/data/designs/ios-apple-wallet-swiftui.md +425 -0
  81. package/dist/data/designs/ios-apple-wallet.md +360 -0
  82. package/dist/data/designs/ios-asana-android.md +435 -0
  83. package/dist/data/designs/ios-asana-expo.md +411 -0
  84. package/dist/data/designs/ios-asana-swiftui.md +416 -0
  85. package/dist/data/designs/ios-asana.md +433 -0
  86. package/dist/data/designs/ios-audible-android.md +450 -0
  87. package/dist/data/designs/ios-audible-expo.md +328 -0
  88. package/dist/data/designs/ios-audible-swiftui.md +418 -0
  89. package/dist/data/designs/ios-audible.md +364 -0
  90. package/dist/data/designs/ios-bandcamp-android.md +471 -0
  91. package/dist/data/designs/ios-bandcamp-expo.md +378 -0
  92. package/dist/data/designs/ios-bandcamp-swiftui.md +374 -0
  93. package/dist/data/designs/ios-bandcamp.md +372 -0
  94. package/dist/data/designs/ios-bear-android.md +496 -0
  95. package/dist/data/designs/ios-bear-expo.md +449 -0
  96. package/dist/data/designs/ios-bear-swiftui.md +479 -0
  97. package/dist/data/designs/ios-bear.md +412 -0
  98. package/dist/data/designs/ios-bereal-android.md +392 -0
  99. package/dist/data/designs/ios-bereal-expo.md +299 -0
  100. package/dist/data/designs/ios-bereal-swiftui.md +319 -0
  101. package/dist/data/designs/ios-bereal.md +336 -0
  102. package/dist/data/designs/ios-binance-android.md +481 -0
  103. package/dist/data/designs/ios-binance-expo.md +404 -0
  104. package/dist/data/designs/ios-binance-swiftui.md +418 -0
  105. package/dist/data/designs/ios-binance.md +410 -0
  106. package/dist/data/designs/ios-bluesky-android.md +442 -0
  107. package/dist/data/designs/ios-bluesky-expo.md +362 -0
  108. package/dist/data/designs/ios-bluesky-swiftui.md +328 -0
  109. package/dist/data/designs/ios-bluesky.md +338 -0
  110. package/dist/data/designs/ios-booking-android.md +471 -0
  111. package/dist/data/designs/ios-booking-expo.md +364 -0
  112. package/dist/data/designs/ios-booking-swiftui.md +377 -0
  113. package/dist/data/designs/ios-booking.md +346 -0
  114. package/dist/data/designs/ios-bumble-android.md +756 -0
  115. package/dist/data/designs/ios-bumble-expo.md +629 -0
  116. package/dist/data/designs/ios-bumble-swiftui.md +546 -0
  117. package/dist/data/designs/ios-bumble.md +424 -0
  118. package/dist/data/designs/ios-cal-ai-android.md +664 -0
  119. package/dist/data/designs/ios-cal-ai-expo.md +415 -0
  120. package/dist/data/designs/ios-cal-ai-swiftui.md +486 -0
  121. package/dist/data/designs/ios-cal-ai.md +387 -0
  122. package/dist/data/designs/ios-calm-android.md +431 -0
  123. package/dist/data/designs/ios-calm-expo.md +384 -0
  124. package/dist/data/designs/ios-calm-swiftui.md +327 -0
  125. package/dist/data/designs/ios-calm.md +356 -0
  126. package/dist/data/designs/ios-canva-android.md +469 -0
  127. package/dist/data/designs/ios-canva-expo.md +374 -0
  128. package/dist/data/designs/ios-canva-swiftui.md +422 -0
  129. package/dist/data/designs/ios-canva.md +395 -0
  130. package/dist/data/designs/ios-cash-app-android.md +601 -0
  131. package/dist/data/designs/ios-cash-app-expo.md +453 -0
  132. package/dist/data/designs/ios-cash-app-swiftui.md +463 -0
  133. package/dist/data/designs/ios-cash-app.md +365 -0
  134. package/dist/data/designs/ios-character-ai-android.md +489 -0
  135. package/dist/data/designs/ios-character-ai-expo.md +420 -0
  136. package/dist/data/designs/ios-character-ai-swiftui.md +417 -0
  137. package/dist/data/designs/ios-character-ai.md +392 -0
  138. package/dist/data/designs/ios-charles-schwab-android.md +454 -0
  139. package/dist/data/designs/ios-charles-schwab-expo.md +388 -0
  140. package/dist/data/designs/ios-charles-schwab-swiftui.md +394 -0
  141. package/dist/data/designs/ios-charles-schwab.md +380 -0
  142. package/dist/data/designs/ios-chatgpt-android.md +753 -0
  143. package/dist/data/designs/ios-chatgpt-expo.md +644 -0
  144. package/dist/data/designs/ios-chatgpt-swiftui.md +653 -0
  145. package/dist/data/designs/ios-chatgpt.md +466 -0
  146. package/dist/data/designs/ios-chime-android.md +438 -0
  147. package/dist/data/designs/ios-chime-expo.md +419 -0
  148. package/dist/data/designs/ios-chime-swiftui.md +383 -0
  149. package/dist/data/designs/ios-chime.md +389 -0
  150. package/dist/data/designs/ios-chipotle-android.md +397 -0
  151. package/dist/data/designs/ios-chipotle-expo.md +301 -0
  152. package/dist/data/designs/ios-chipotle-swiftui.md +345 -0
  153. package/dist/data/designs/ios-chipotle.md +340 -0
  154. package/dist/data/designs/ios-citymapper-android.md +466 -0
  155. package/dist/data/designs/ios-citymapper-expo.md +420 -0
  156. package/dist/data/designs/ios-citymapper-swiftui.md +424 -0
  157. package/dist/data/designs/ios-citymapper.md +394 -0
  158. package/dist/data/designs/ios-claude-android.md +625 -0
  159. package/dist/data/designs/ios-claude-expo.md +671 -0
  160. package/dist/data/designs/ios-claude-swiftui.md +649 -0
  161. package/dist/data/designs/ios-claude.md +447 -0
  162. package/dist/data/designs/ios-clickup-android.md +484 -0
  163. package/dist/data/designs/ios-clickup-expo.md +423 -0
  164. package/dist/data/designs/ios-clickup-swiftui.md +416 -0
  165. package/dist/data/designs/ios-clickup.md +431 -0
  166. package/dist/data/designs/ios-clubhouse-android.md +524 -0
  167. package/dist/data/designs/ios-clubhouse-expo.md +425 -0
  168. package/dist/data/designs/ios-clubhouse-swiftui.md +447 -0
  169. package/dist/data/designs/ios-clubhouse.md +406 -0
  170. package/dist/data/designs/ios-coffee-meets-bagel-android.md +461 -0
  171. package/dist/data/designs/ios-coffee-meets-bagel-expo.md +372 -0
  172. package/dist/data/designs/ios-coffee-meets-bagel-swiftui.md +368 -0
  173. package/dist/data/designs/ios-coffee-meets-bagel.md +376 -0
  174. package/dist/data/designs/ios-coinbase-android.md +611 -0
  175. package/dist/data/designs/ios-coinbase-expo.md +500 -0
  176. package/dist/data/designs/ios-coinbase-swiftui.md +490 -0
  177. package/dist/data/designs/ios-coinbase.md +409 -0
  178. package/dist/data/designs/ios-copilot-android.md +625 -0
  179. package/dist/data/designs/ios-copilot-expo.md +423 -0
  180. package/dist/data/designs/ios-copilot-swiftui.md +471 -0
  181. package/dist/data/designs/ios-copilot.md +367 -0
  182. package/dist/data/designs/ios-craft-android.md +459 -0
  183. package/dist/data/designs/ios-craft-expo.md +417 -0
  184. package/dist/data/designs/ios-craft-swiftui.md +449 -0
  185. package/dist/data/designs/ios-craft.md +449 -0
  186. package/dist/data/designs/ios-crunchyroll-android.md +432 -0
  187. package/dist/data/designs/ios-crunchyroll-expo.md +388 -0
  188. package/dist/data/designs/ios-crunchyroll-swiftui.md +417 -0
  189. package/dist/data/designs/ios-crunchyroll.md +388 -0
  190. package/dist/data/designs/ios-crypto-com-android.md +461 -0
  191. package/dist/data/designs/ios-crypto-com-expo.md +404 -0
  192. package/dist/data/designs/ios-crypto-com-swiftui.md +419 -0
  193. package/dist/data/designs/ios-crypto-com.md +410 -0
  194. package/dist/data/designs/ios-deepseek-android.md +471 -0
  195. package/dist/data/designs/ios-deepseek-expo.md +391 -0
  196. package/dist/data/designs/ios-deepseek-swiftui.md +354 -0
  197. package/dist/data/designs/ios-deepseek.md +393 -0
  198. package/dist/data/designs/ios-deezer-android.md +475 -0
  199. package/dist/data/designs/ios-deezer-expo.md +400 -0
  200. package/dist/data/designs/ios-deezer-swiftui.md +430 -0
  201. package/dist/data/designs/ios-deezer.md +388 -0
  202. package/dist/data/designs/ios-deliveroo-android.md +493 -0
  203. package/dist/data/designs/ios-deliveroo-expo.md +424 -0
  204. package/dist/data/designs/ios-deliveroo-swiftui.md +398 -0
  205. package/dist/data/designs/ios-deliveroo.md +420 -0
  206. package/dist/data/designs/ios-delta-android.md +439 -0
  207. package/dist/data/designs/ios-delta-expo.md +381 -0
  208. package/dist/data/designs/ios-delta-swiftui.md +400 -0
  209. package/dist/data/designs/ios-delta.md +397 -0
  210. package/dist/data/designs/ios-discord-android.md +611 -0
  211. package/dist/data/designs/ios-discord-expo.md +618 -0
  212. package/dist/data/designs/ios-discord-swiftui.md +630 -0
  213. package/dist/data/designs/ios-discord.md +451 -0
  214. package/dist/data/designs/ios-disney-plus-android.md +464 -0
  215. package/dist/data/designs/ios-disney-plus-expo.md +358 -0
  216. package/dist/data/designs/ios-disney-plus-swiftui.md +412 -0
  217. package/dist/data/designs/ios-disney-plus.md +355 -0
  218. package/dist/data/designs/ios-dominos-android.md +417 -0
  219. package/dist/data/designs/ios-dominos-expo.md +316 -0
  220. package/dist/data/designs/ios-dominos-swiftui.md +340 -0
  221. package/dist/data/designs/ios-dominos.md +347 -0
  222. package/dist/data/designs/ios-doordash-android.md +527 -0
  223. package/dist/data/designs/ios-doordash-expo.md +323 -0
  224. package/dist/data/designs/ios-doordash-swiftui.md +301 -0
  225. package/dist/data/designs/ios-doordash.md +393 -0
  226. package/dist/data/designs/ios-dropbox-android.md +522 -0
  227. package/dist/data/designs/ios-dropbox-expo.md +393 -0
  228. package/dist/data/designs/ios-dropbox-swiftui.md +400 -0
  229. package/dist/data/designs/ios-dropbox.md +374 -0
  230. package/dist/data/designs/ios-duolingo-android.md +641 -0
  231. package/dist/data/designs/ios-duolingo-expo.md +597 -0
  232. package/dist/data/designs/ios-duolingo-swiftui.md +539 -0
  233. package/dist/data/designs/ios-duolingo.md +409 -0
  234. package/dist/data/designs/ios-ebay-android.md +436 -0
  235. package/dist/data/designs/ios-ebay-expo.md +344 -0
  236. package/dist/data/designs/ios-ebay-swiftui.md +308 -0
  237. package/dist/data/designs/ios-ebay.md +355 -0
  238. package/dist/data/designs/ios-espn-android.md +468 -0
  239. package/dist/data/designs/ios-espn-expo.md +387 -0
  240. package/dist/data/designs/ios-espn-swiftui.md +410 -0
  241. package/dist/data/designs/ios-espn.md +384 -0
  242. package/dist/data/designs/ios-etsy-android.md +439 -0
  243. package/dist/data/designs/ios-etsy-expo.md +351 -0
  244. package/dist/data/designs/ios-etsy-swiftui.md +296 -0
  245. package/dist/data/designs/ios-etsy.md +355 -0
  246. package/dist/data/designs/ios-evernote-android.md +419 -0
  247. package/dist/data/designs/ios-evernote-expo.md +379 -0
  248. package/dist/data/designs/ios-evernote-swiftui.md +380 -0
  249. package/dist/data/designs/ios-evernote.md +416 -0
  250. package/dist/data/designs/ios-expedia-android.md +451 -0
  251. package/dist/data/designs/ios-expedia-expo.md +433 -0
  252. package/dist/data/designs/ios-expedia-swiftui.md +399 -0
  253. package/dist/data/designs/ios-expedia.md +431 -0
  254. package/dist/data/designs/ios-facebook-android.md +628 -0
  255. package/dist/data/designs/ios-facebook-expo.md +471 -0
  256. package/dist/data/designs/ios-facebook-swiftui.md +459 -0
  257. package/dist/data/designs/ios-facebook.md +452 -0
  258. package/dist/data/designs/ios-feeld-android.md +431 -0
  259. package/dist/data/designs/ios-feeld-expo.md +379 -0
  260. package/dist/data/designs/ios-feeld-swiftui.md +401 -0
  261. package/dist/data/designs/ios-feeld.md +378 -0
  262. package/dist/data/designs/ios-fidelity-android.md +426 -0
  263. package/dist/data/designs/ios-fidelity-expo.md +396 -0
  264. package/dist/data/designs/ios-fidelity-swiftui.md +398 -0
  265. package/dist/data/designs/ios-fidelity.md +387 -0
  266. package/dist/data/designs/ios-figma-android.md +578 -0
  267. package/dist/data/designs/ios-figma-expo.md +504 -0
  268. package/dist/data/designs/ios-figma-swiftui.md +542 -0
  269. package/dist/data/designs/ios-figma.md +404 -0
  270. package/dist/data/designs/ios-fitbit-android.md +439 -0
  271. package/dist/data/designs/ios-fitbit-expo.md +389 -0
  272. package/dist/data/designs/ios-fitbit-swiftui.md +380 -0
  273. package/dist/data/designs/ios-fitbit.md +396 -0
  274. package/dist/data/designs/ios-flickr-android.md +506 -0
  275. package/dist/data/designs/ios-flickr-expo.md +434 -0
  276. package/dist/data/designs/ios-flickr-swiftui.md +421 -0
  277. package/dist/data/designs/ios-flickr.md +394 -0
  278. package/dist/data/designs/ios-flighty-android.md +418 -0
  279. package/dist/data/designs/ios-flighty-expo.md +353 -0
  280. package/dist/data/designs/ios-flighty-swiftui.md +337 -0
  281. package/dist/data/designs/ios-flighty.md +357 -0
  282. package/dist/data/designs/ios-flo-android.md +447 -0
  283. package/dist/data/designs/ios-flo-expo.md +363 -0
  284. package/dist/data/designs/ios-flo-swiftui.md +355 -0
  285. package/dist/data/designs/ios-flo.md +351 -0
  286. package/dist/data/designs/ios-garmin-connect-android.md +531 -0
  287. package/dist/data/designs/ios-garmin-connect-expo.md +429 -0
  288. package/dist/data/designs/ios-garmin-connect-swiftui.md +459 -0
  289. package/dist/data/designs/ios-garmin-connect.md +419 -0
  290. package/dist/data/designs/ios-gas-android.md +438 -0
  291. package/dist/data/designs/ios-gas-expo.md +350 -0
  292. package/dist/data/designs/ios-gas-swiftui.md +329 -0
  293. package/dist/data/designs/ios-gas.md +387 -0
  294. package/dist/data/designs/ios-gemini-android.md +568 -0
  295. package/dist/data/designs/ios-gemini-expo.md +416 -0
  296. package/dist/data/designs/ios-gemini-swiftui.md +424 -0
  297. package/dist/data/designs/ios-gemini.md +351 -0
  298. package/dist/data/designs/ios-github-android.md +507 -0
  299. package/dist/data/designs/ios-github-expo.md +486 -0
  300. package/dist/data/designs/ios-github-swiftui.md +459 -0
  301. package/dist/data/designs/ios-github.md +394 -0
  302. package/dist/data/designs/ios-gmail-android.md +548 -0
  303. package/dist/data/designs/ios-gmail-expo.md +457 -0
  304. package/dist/data/designs/ios-gmail-swiftui.md +470 -0
  305. package/dist/data/designs/ios-gmail.md +441 -0
  306. package/dist/data/designs/ios-goodreads-android.md +436 -0
  307. package/dist/data/designs/ios-goodreads-expo.md +407 -0
  308. package/dist/data/designs/ios-goodreads-swiftui.md +378 -0
  309. package/dist/data/designs/ios-goodreads.md +385 -0
  310. package/dist/data/designs/ios-google-calendar-android.md +565 -0
  311. package/dist/data/designs/ios-google-calendar-expo.md +616 -0
  312. package/dist/data/designs/ios-google-calendar-swiftui.md +585 -0
  313. package/dist/data/designs/ios-google-calendar.md +431 -0
  314. package/dist/data/designs/ios-google-maps-android.md +614 -0
  315. package/dist/data/designs/ios-google-maps-expo.md +515 -0
  316. package/dist/data/designs/ios-google-maps-swiftui.md +484 -0
  317. package/dist/data/designs/ios-google-maps.md +451 -0
  318. package/dist/data/designs/ios-grammarly-android.md +449 -0
  319. package/dist/data/designs/ios-grammarly-expo.md +383 -0
  320. package/dist/data/designs/ios-grammarly-swiftui.md +381 -0
  321. package/dist/data/designs/ios-grammarly.md +392 -0
  322. package/dist/data/designs/ios-grindr-android.md +494 -0
  323. package/dist/data/designs/ios-grindr-expo.md +358 -0
  324. package/dist/data/designs/ios-grindr-swiftui.md +357 -0
  325. package/dist/data/designs/ios-grindr.md +356 -0
  326. package/dist/data/designs/ios-grok-android.md +471 -0
  327. package/dist/data/designs/ios-grok-expo.md +388 -0
  328. package/dist/data/designs/ios-grok-swiftui.md +397 -0
  329. package/dist/data/designs/ios-grok.md +357 -0
  330. package/dist/data/designs/ios-groupme-android.md +551 -0
  331. package/dist/data/designs/ios-groupme-expo.md +442 -0
  332. package/dist/data/designs/ios-groupme-swiftui.md +439 -0
  333. package/dist/data/designs/ios-groupme.md +424 -0
  334. package/dist/data/designs/ios-grubhub-android.md +506 -0
  335. package/dist/data/designs/ios-grubhub-expo.md +428 -0
  336. package/dist/data/designs/ios-grubhub-swiftui.md +408 -0
  337. package/dist/data/designs/ios-grubhub.md +427 -0
  338. package/dist/data/designs/ios-happn-android.md +464 -0
  339. package/dist/data/designs/ios-happn-expo.md +411 -0
  340. package/dist/data/designs/ios-happn-swiftui.md +401 -0
  341. package/dist/data/designs/ios-happn.md +400 -0
  342. package/dist/data/designs/ios-headspace-android.md +688 -0
  343. package/dist/data/designs/ios-headspace-expo.md +574 -0
  344. package/dist/data/designs/ios-headspace-swiftui.md +498 -0
  345. package/dist/data/designs/ios-headspace.md +430 -0
  346. package/dist/data/designs/ios-hevy-android.md +473 -0
  347. package/dist/data/designs/ios-hevy-expo.md +405 -0
  348. package/dist/data/designs/ios-hevy-swiftui.md +367 -0
  349. package/dist/data/designs/ios-hevy.md +410 -0
  350. package/dist/data/designs/ios-hinge-android.md +743 -0
  351. package/dist/data/designs/ios-hinge-expo.md +580 -0
  352. package/dist/data/designs/ios-hinge-swiftui.md +512 -0
  353. package/dist/data/designs/ios-hinge.md +405 -0
  354. package/dist/data/designs/ios-hopper-android.md +440 -0
  355. package/dist/data/designs/ios-hopper-expo.md +353 -0
  356. package/dist/data/designs/ios-hopper-swiftui.md +340 -0
  357. package/dist/data/designs/ios-hopper.md +354 -0
  358. package/dist/data/designs/ios-hulu-android.md +435 -0
  359. package/dist/data/designs/ios-hulu-expo.md +331 -0
  360. package/dist/data/designs/ios-hulu-swiftui.md +374 -0
  361. package/dist/data/designs/ios-hulu.md +353 -0
  362. package/dist/data/designs/ios-iheartradio-android.md +481 -0
  363. package/dist/data/designs/ios-iheartradio-expo.md +417 -0
  364. package/dist/data/designs/ios-iheartradio-swiftui.md +423 -0
  365. package/dist/data/designs/ios-iheartradio.md +381 -0
  366. package/dist/data/designs/ios-imessage-android.md +426 -0
  367. package/dist/data/designs/ios-imessage-expo.md +384 -0
  368. package/dist/data/designs/ios-imessage-swiftui.md +378 -0
  369. package/dist/data/designs/ios-imessage.md +394 -0
  370. package/dist/data/designs/ios-instacart-android.md +471 -0
  371. package/dist/data/designs/ios-instacart-expo.md +349 -0
  372. package/dist/data/designs/ios-instacart-swiftui.md +378 -0
  373. package/dist/data/designs/ios-instacart.md +360 -0
  374. package/dist/data/designs/ios-instagram-android.md +646 -0
  375. package/dist/data/designs/ios-instagram-expo.md +310 -0
  376. package/dist/data/designs/ios-instagram-swiftui.md +333 -0
  377. package/dist/data/designs/ios-instagram.md +376 -0
  378. package/dist/data/designs/ios-jira-android.md +432 -0
  379. package/dist/data/designs/ios-jira-expo.md +375 -0
  380. package/dist/data/designs/ios-jira-swiftui.md +433 -0
  381. package/dist/data/designs/ios-jira.md +424 -0
  382. package/dist/data/designs/ios-kakaotalk-android.md +491 -0
  383. package/dist/data/designs/ios-kakaotalk-expo.md +418 -0
  384. package/dist/data/designs/ios-kakaotalk-swiftui.md +406 -0
  385. package/dist/data/designs/ios-kakaotalk.md +414 -0
  386. package/dist/data/designs/ios-kayak-android.md +466 -0
  387. package/dist/data/designs/ios-kayak-expo.md +407 -0
  388. package/dist/data/designs/ios-kayak-swiftui.md +426 -0
  389. package/dist/data/designs/ios-kayak.md +392 -0
  390. package/dist/data/designs/ios-kick-android.md +487 -0
  391. package/dist/data/designs/ios-kick-expo.md +434 -0
  392. package/dist/data/designs/ios-kick-swiftui.md +429 -0
  393. package/dist/data/designs/ios-kick.md +389 -0
  394. package/dist/data/designs/ios-kik-android.md +433 -0
  395. package/dist/data/designs/ios-kik-expo.md +363 -0
  396. package/dist/data/designs/ios-kik-swiftui.md +363 -0
  397. package/dist/data/designs/ios-kik.md +392 -0
  398. package/dist/data/designs/ios-kindle-android.md +439 -0
  399. package/dist/data/designs/ios-kindle-expo.md +356 -0
  400. package/dist/data/designs/ios-kindle-swiftui.md +372 -0
  401. package/dist/data/designs/ios-kindle.md +369 -0
  402. package/dist/data/designs/ios-klarna-android.md +420 -0
  403. package/dist/data/designs/ios-klarna-expo.md +349 -0
  404. package/dist/data/designs/ios-klarna-swiftui.md +360 -0
  405. package/dist/data/designs/ios-klarna.md +356 -0
  406. package/dist/data/designs/ios-lemon8-android.md +492 -0
  407. package/dist/data/designs/ios-lemon8-expo.md +413 -0
  408. package/dist/data/designs/ios-lemon8-swiftui.md +428 -0
  409. package/dist/data/designs/ios-lemon8.md +378 -0
  410. package/dist/data/designs/ios-life360-android.md +474 -0
  411. package/dist/data/designs/ios-life360-expo.md +375 -0
  412. package/dist/data/designs/ios-life360-swiftui.md +390 -0
  413. package/dist/data/designs/ios-life360.md +402 -0
  414. package/dist/data/designs/ios-line-android.md +517 -0
  415. package/dist/data/designs/ios-line-expo.md +402 -0
  416. package/dist/data/designs/ios-line-swiftui.md +361 -0
  417. package/dist/data/designs/ios-line.md +362 -0
  418. package/dist/data/designs/ios-linear-android.md +457 -0
  419. package/dist/data/designs/ios-linear-expo.md +367 -0
  420. package/dist/data/designs/ios-linear-swiftui.md +401 -0
  421. package/dist/data/designs/ios-linear.md +368 -0
  422. package/dist/data/designs/ios-linkedin-android.md +620 -0
  423. package/dist/data/designs/ios-linkedin-expo.md +469 -0
  424. package/dist/data/designs/ios-linkedin-swiftui.md +472 -0
  425. package/dist/data/designs/ios-linkedin.md +444 -0
  426. package/dist/data/designs/ios-locket-android.md +500 -0
  427. package/dist/data/designs/ios-locket-expo.md +375 -0
  428. package/dist/data/designs/ios-locket-swiftui.md +375 -0
  429. package/dist/data/designs/ios-locket.md +381 -0
  430. package/dist/data/designs/ios-lyft-android.md +406 -0
  431. package/dist/data/designs/ios-lyft-expo.md +333 -0
  432. package/dist/data/designs/ios-lyft-swiftui.md +315 -0
  433. package/dist/data/designs/ios-lyft.md +337 -0
  434. package/dist/data/designs/ios-marriott-bonvoy-android.md +488 -0
  435. package/dist/data/designs/ios-marriott-bonvoy-expo.md +412 -0
  436. package/dist/data/designs/ios-marriott-bonvoy-swiftui.md +461 -0
  437. package/dist/data/designs/ios-marriott-bonvoy.md +379 -0
  438. package/dist/data/designs/ios-mastodon-android.md +476 -0
  439. package/dist/data/designs/ios-mastodon-expo.md +379 -0
  440. package/dist/data/designs/ios-mastodon-swiftui.md +349 -0
  441. package/dist/data/designs/ios-mastodon.md +337 -0
  442. package/dist/data/designs/ios-match-android.md +496 -0
  443. package/dist/data/designs/ios-match-expo.md +393 -0
  444. package/dist/data/designs/ios-match-swiftui.md +450 -0
  445. package/dist/data/designs/ios-match.md +382 -0
  446. package/dist/data/designs/ios-max-android.md +454 -0
  447. package/dist/data/designs/ios-max-expo.md +342 -0
  448. package/dist/data/designs/ios-max-swiftui.md +332 -0
  449. package/dist/data/designs/ios-max.md +352 -0
  450. package/dist/data/designs/ios-mcdonalds-android.md +497 -0
  451. package/dist/data/designs/ios-mcdonalds-expo.md +382 -0
  452. package/dist/data/designs/ios-mcdonalds-swiftui.md +394 -0
  453. package/dist/data/designs/ios-mcdonalds.md +410 -0
  454. package/dist/data/designs/ios-messenger-android.md +523 -0
  455. package/dist/data/designs/ios-messenger-expo.md +379 -0
  456. package/dist/data/designs/ios-messenger-swiftui.md +369 -0
  457. package/dist/data/designs/ios-messenger.md +361 -0
  458. package/dist/data/designs/ios-microsoft-teams-android.md +446 -0
  459. package/dist/data/designs/ios-microsoft-teams-expo.md +362 -0
  460. package/dist/data/designs/ios-microsoft-teams-swiftui.md +384 -0
  461. package/dist/data/designs/ios-microsoft-teams.md +359 -0
  462. package/dist/data/designs/ios-midjourney-android.md +503 -0
  463. package/dist/data/designs/ios-midjourney-expo.md +406 -0
  464. package/dist/data/designs/ios-midjourney-swiftui.md +376 -0
  465. package/dist/data/designs/ios-midjourney.md +407 -0
  466. package/dist/data/designs/ios-miro-android.md +475 -0
  467. package/dist/data/designs/ios-miro-expo.md +421 -0
  468. package/dist/data/designs/ios-miro-swiftui.md +407 -0
  469. package/dist/data/designs/ios-miro.md +424 -0
  470. package/dist/data/designs/ios-monday-android.md +426 -0
  471. package/dist/data/designs/ios-monday-expo.md +382 -0
  472. package/dist/data/designs/ios-monday-swiftui.md +386 -0
  473. package/dist/data/designs/ios-monday.md +415 -0
  474. package/dist/data/designs/ios-monzo-android.md +423 -0
  475. package/dist/data/designs/ios-monzo-expo.md +391 -0
  476. package/dist/data/designs/ios-monzo-swiftui.md +371 -0
  477. package/dist/data/designs/ios-monzo.md +382 -0
  478. package/dist/data/designs/ios-myfitnesspal-android.md +631 -0
  479. package/dist/data/designs/ios-myfitnesspal-expo.md +489 -0
  480. package/dist/data/designs/ios-myfitnesspal-swiftui.md +500 -0
  481. package/dist/data/designs/ios-myfitnesspal.md +408 -0
  482. package/dist/data/designs/ios-netflix-android.md +570 -0
  483. package/dist/data/designs/ios-netflix-expo.md +528 -0
  484. package/dist/data/designs/ios-netflix-swiftui.md +543 -0
  485. package/dist/data/designs/ios-netflix.md +476 -0
  486. package/dist/data/designs/ios-nextdoor-android.md +399 -0
  487. package/dist/data/designs/ios-nextdoor-expo.md +317 -0
  488. package/dist/data/designs/ios-nextdoor-swiftui.md +343 -0
  489. package/dist/data/designs/ios-nextdoor.md +332 -0
  490. package/dist/data/designs/ios-nike-run-club-android.md +598 -0
  491. package/dist/data/designs/ios-nike-run-club-expo.md +459 -0
  492. package/dist/data/designs/ios-nike-run-club-swiftui.md +474 -0
  493. package/dist/data/designs/ios-nike-run-club.md +400 -0
  494. package/dist/data/designs/ios-noom-android.md +455 -0
  495. package/dist/data/designs/ios-noom-expo.md +362 -0
  496. package/dist/data/designs/ios-noom-swiftui.md +369 -0
  497. package/dist/data/designs/ios-noom.md +404 -0
  498. package/dist/data/designs/ios-notion-android.md +575 -0
  499. package/dist/data/designs/ios-notion-expo.md +543 -0
  500. package/dist/data/designs/ios-notion-swiftui.md +562 -0
  501. package/dist/data/designs/ios-notion.md +506 -0
  502. package/dist/data/designs/ios-nubank-android.md +447 -0
  503. package/dist/data/designs/ios-nubank-expo.md +391 -0
  504. package/dist/data/designs/ios-nubank-swiftui.md +391 -0
  505. package/dist/data/designs/ios-nubank.md +388 -0
  506. package/dist/data/designs/ios-obsidian-android.md +456 -0
  507. package/dist/data/designs/ios-obsidian-expo.md +401 -0
  508. package/dist/data/designs/ios-obsidian-swiftui.md +412 -0
  509. package/dist/data/designs/ios-obsidian.md +363 -0
  510. package/dist/data/designs/ios-okcupid-android.md +496 -0
  511. package/dist/data/designs/ios-okcupid-expo.md +378 -0
  512. package/dist/data/designs/ios-okcupid-swiftui.md +343 -0
  513. package/dist/data/designs/ios-okcupid.md +364 -0
  514. package/dist/data/designs/ios-opentable-android.md +426 -0
  515. package/dist/data/designs/ios-opentable-expo.md +350 -0
  516. package/dist/data/designs/ios-opentable-swiftui.md +328 -0
  517. package/dist/data/designs/ios-opentable.md +411 -0
  518. package/dist/data/designs/ios-oura-android.md +426 -0
  519. package/dist/data/designs/ios-oura-expo.md +353 -0
  520. package/dist/data/designs/ios-oura-swiftui.md +327 -0
  521. package/dist/data/designs/ios-oura.md +356 -0
  522. package/dist/data/designs/ios-overcast-android.md +508 -0
  523. package/dist/data/designs/ios-overcast-expo.md +420 -0
  524. package/dist/data/designs/ios-overcast-swiftui.md +427 -0
  525. package/dist/data/designs/ios-overcast.md +414 -0
  526. package/dist/data/designs/ios-pandora-android.md +477 -0
  527. package/dist/data/designs/ios-pandora-expo.md +406 -0
  528. package/dist/data/designs/ios-pandora-swiftui.md +413 -0
  529. package/dist/data/designs/ios-pandora.md +366 -0
  530. package/dist/data/designs/ios-panera-android.md +414 -0
  531. package/dist/data/designs/ios-panera-expo.md +352 -0
  532. package/dist/data/designs/ios-panera-swiftui.md +369 -0
  533. package/dist/data/designs/ios-panera.md +412 -0
  534. package/dist/data/designs/ios-paramount-plus-android.md +415 -0
  535. package/dist/data/designs/ios-paramount-plus-expo.md +363 -0
  536. package/dist/data/designs/ios-paramount-plus-swiftui.md +372 -0
  537. package/dist/data/designs/ios-paramount-plus.md +400 -0
  538. package/dist/data/designs/ios-paypal-android.md +535 -0
  539. package/dist/data/designs/ios-paypal-expo.md +429 -0
  540. package/dist/data/designs/ios-paypal-swiftui.md +466 -0
  541. package/dist/data/designs/ios-paypal.md +393 -0
  542. package/dist/data/designs/ios-peacock-android.md +453 -0
  543. package/dist/data/designs/ios-peacock-expo.md +393 -0
  544. package/dist/data/designs/ios-peacock-swiftui.md +420 -0
  545. package/dist/data/designs/ios-peacock.md +411 -0
  546. package/dist/data/designs/ios-peloton-android.md +470 -0
  547. package/dist/data/designs/ios-peloton-expo.md +401 -0
  548. package/dist/data/designs/ios-peloton-swiftui.md +409 -0
  549. package/dist/data/designs/ios-peloton.md +415 -0
  550. package/dist/data/designs/ios-perplexity-android.md +553 -0
  551. package/dist/data/designs/ios-perplexity-expo.md +703 -0
  552. package/dist/data/designs/ios-perplexity-swiftui.md +602 -0
  553. package/dist/data/designs/ios-perplexity.md +453 -0
  554. package/dist/data/designs/ios-pinterest-android.md +551 -0
  555. package/dist/data/designs/ios-pinterest-expo.md +466 -0
  556. package/dist/data/designs/ios-pinterest-swiftui.md +464 -0
  557. package/dist/data/designs/ios-pinterest.md +427 -0
  558. package/dist/data/designs/ios-plenty-of-fish-android.md +462 -0
  559. package/dist/data/designs/ios-plenty-of-fish-expo.md +380 -0
  560. package/dist/data/designs/ios-plenty-of-fish-swiftui.md +429 -0
  561. package/dist/data/designs/ios-plenty-of-fish.md +387 -0
  562. package/dist/data/designs/ios-plex-android.md +403 -0
  563. package/dist/data/designs/ios-plex-expo.md +333 -0
  564. package/dist/data/designs/ios-plex-swiftui.md +349 -0
  565. package/dist/data/designs/ios-plex.md +379 -0
  566. package/dist/data/designs/ios-pluto-tv-android.md +413 -0
  567. package/dist/data/designs/ios-pluto-tv-expo.md +379 -0
  568. package/dist/data/designs/ios-pluto-tv-swiftui.md +411 -0
  569. package/dist/data/designs/ios-pluto-tv.md +362 -0
  570. package/dist/data/designs/ios-pocket-casts-android.md +492 -0
  571. package/dist/data/designs/ios-pocket-casts-expo.md +430 -0
  572. package/dist/data/designs/ios-pocket-casts-swiftui.md +479 -0
  573. package/dist/data/designs/ios-pocket-casts.md +427 -0
  574. package/dist/data/designs/ios-postman-android.md +472 -0
  575. package/dist/data/designs/ios-postman-expo.md +372 -0
  576. package/dist/data/designs/ios-postman-swiftui.md +377 -0
  577. package/dist/data/designs/ios-postman.md +405 -0
  578. package/dist/data/designs/ios-prime-video-android.md +447 -0
  579. package/dist/data/designs/ios-prime-video-expo.md +365 -0
  580. package/dist/data/designs/ios-prime-video-swiftui.md +333 -0
  581. package/dist/data/designs/ios-prime-video.md +351 -0
  582. package/dist/data/designs/ios-quora-android.md +513 -0
  583. package/dist/data/designs/ios-quora-expo.md +362 -0
  584. package/dist/data/designs/ios-quora-swiftui.md +375 -0
  585. package/dist/data/designs/ios-quora.md +359 -0
  586. package/dist/data/designs/ios-raya-android.md +401 -0
  587. package/dist/data/designs/ios-raya-expo.md +366 -0
  588. package/dist/data/designs/ios-raya-swiftui.md +393 -0
  589. package/dist/data/designs/ios-raya.md +366 -0
  590. package/dist/data/designs/ios-reddit-android.md +605 -0
  591. package/dist/data/designs/ios-reddit-expo.md +553 -0
  592. package/dist/data/designs/ios-reddit-swiftui.md +514 -0
  593. package/dist/data/designs/ios-reddit.md +460 -0
  594. package/dist/data/designs/ios-resy-android.md +430 -0
  595. package/dist/data/designs/ios-resy-expo.md +344 -0
  596. package/dist/data/designs/ios-resy-swiftui.md +330 -0
  597. package/dist/data/designs/ios-resy.md +412 -0
  598. package/dist/data/designs/ios-revolut-android.md +433 -0
  599. package/dist/data/designs/ios-revolut-expo.md +379 -0
  600. package/dist/data/designs/ios-revolut-swiftui.md +372 -0
  601. package/dist/data/designs/ios-revolut.md +353 -0
  602. package/dist/data/designs/ios-robinhood-android.md +587 -0
  603. package/dist/data/designs/ios-robinhood-expo.md +416 -0
  604. package/dist/data/designs/ios-robinhood-swiftui.md +431 -0
  605. package/dist/data/designs/ios-robinhood.md +380 -0
  606. package/dist/data/designs/ios-runna-android.md +485 -0
  607. package/dist/data/designs/ios-runna-expo.md +388 -0
  608. package/dist/data/designs/ios-runna-swiftui.md +413 -0
  609. package/dist/data/designs/ios-runna.md +390 -0
  610. package/dist/data/designs/ios-shazam-android.md +436 -0
  611. package/dist/data/designs/ios-shazam-expo.md +348 -0
  612. package/dist/data/designs/ios-shazam-swiftui.md +394 -0
  613. package/dist/data/designs/ios-shazam.md +338 -0
  614. package/dist/data/designs/ios-signal-android.md +462 -0
  615. package/dist/data/designs/ios-signal-expo.md +361 -0
  616. package/dist/data/designs/ios-signal-swiftui.md +350 -0
  617. package/dist/data/designs/ios-signal.md +357 -0
  618. package/dist/data/designs/ios-skype-android.md +398 -0
  619. package/dist/data/designs/ios-skype-expo.md +368 -0
  620. package/dist/data/designs/ios-skype-swiftui.md +369 -0
  621. package/dist/data/designs/ios-skype.md +406 -0
  622. package/dist/data/designs/ios-skyscanner-android.md +451 -0
  623. package/dist/data/designs/ios-skyscanner-expo.md +423 -0
  624. package/dist/data/designs/ios-skyscanner-swiftui.md +419 -0
  625. package/dist/data/designs/ios-skyscanner.md +421 -0
  626. package/dist/data/designs/ios-slack-android.md +695 -0
  627. package/dist/data/designs/ios-slack-expo.md +601 -0
  628. package/dist/data/designs/ios-slack-swiftui.md +594 -0
  629. package/dist/data/designs/ios-slack.md +474 -0
  630. package/dist/data/designs/ios-sleep-cycle-android.md +436 -0
  631. package/dist/data/designs/ios-sleep-cycle-expo.md +380 -0
  632. package/dist/data/designs/ios-sleep-cycle-swiftui.md +409 -0
  633. package/dist/data/designs/ios-sleep-cycle.md +386 -0
  634. package/dist/data/designs/ios-snapchat-android.md +671 -0
  635. package/dist/data/designs/ios-snapchat-expo.md +528 -0
  636. package/dist/data/designs/ios-snapchat-swiftui.md +557 -0
  637. package/dist/data/designs/ios-snapchat.md +478 -0
  638. package/dist/data/designs/ios-sofi-android.md +446 -0
  639. package/dist/data/designs/ios-sofi-expo.md +387 -0
  640. package/dist/data/designs/ios-sofi-swiftui.md +379 -0
  641. package/dist/data/designs/ios-sofi.md +385 -0
  642. package/dist/data/designs/ios-soundcloud-android.md +488 -0
  643. package/dist/data/designs/ios-soundcloud-expo.md +364 -0
  644. package/dist/data/designs/ios-soundcloud-swiftui.md +399 -0
  645. package/dist/data/designs/ios-soundcloud.md +359 -0
  646. package/dist/data/designs/ios-southwest-android.md +446 -0
  647. package/dist/data/designs/ios-southwest-expo.md +389 -0
  648. package/dist/data/designs/ios-southwest-swiftui.md +405 -0
  649. package/dist/data/designs/ios-southwest.md +405 -0
  650. package/dist/data/designs/ios-spotify-android.md +427 -0
  651. package/dist/data/designs/ios-spotify-expo.md +321 -0
  652. package/dist/data/designs/ios-spotify-swiftui.md +312 -0
  653. package/dist/data/designs/ios-spotify.md +366 -0
  654. package/dist/data/designs/ios-starbucks-android.md +622 -0
  655. package/dist/data/designs/ios-starbucks-expo.md +497 -0
  656. package/dist/data/designs/ios-starbucks-swiftui.md +500 -0
  657. package/dist/data/designs/ios-starbucks.md +440 -0
  658. package/dist/data/designs/ios-strava-android.md +656 -0
  659. package/dist/data/designs/ios-strava-expo.md +501 -0
  660. package/dist/data/designs/ios-strava-swiftui.md +465 -0
  661. package/dist/data/designs/ios-strava.md +433 -0
  662. package/dist/data/designs/ios-strong-android.md +479 -0
  663. package/dist/data/designs/ios-strong-expo.md +396 -0
  664. package/dist/data/designs/ios-strong-swiftui.md +363 -0
  665. package/dist/data/designs/ios-strong.md +415 -0
  666. package/dist/data/designs/ios-substack-android.md +440 -0
  667. package/dist/data/designs/ios-substack-expo.md +395 -0
  668. package/dist/data/designs/ios-substack-swiftui.md +371 -0
  669. package/dist/data/designs/ios-substack.md +372 -0
  670. package/dist/data/designs/ios-swiggy-android.md +549 -0
  671. package/dist/data/designs/ios-swiggy-expo.md +443 -0
  672. package/dist/data/designs/ios-swiggy-swiftui.md +471 -0
  673. package/dist/data/designs/ios-swiggy.md +432 -0
  674. package/dist/data/designs/ios-taco-bell-android.md +529 -0
  675. package/dist/data/designs/ios-taco-bell-expo.md +407 -0
  676. package/dist/data/designs/ios-taco-bell-swiftui.md +419 -0
  677. package/dist/data/designs/ios-taco-bell.md +430 -0
  678. package/dist/data/designs/ios-telegram-android.md +676 -0
  679. package/dist/data/designs/ios-telegram-expo.md +594 -0
  680. package/dist/data/designs/ios-telegram-swiftui.md +518 -0
  681. package/dist/data/designs/ios-telegram.md +458 -0
  682. package/dist/data/designs/ios-the-league-android.md +454 -0
  683. package/dist/data/designs/ios-the-league-expo.md +391 -0
  684. package/dist/data/designs/ios-the-league-swiftui.md +409 -0
  685. package/dist/data/designs/ios-the-league.md +368 -0
  686. package/dist/data/designs/ios-things-3-android.md +421 -0
  687. package/dist/data/designs/ios-things-3-expo.md +351 -0
  688. package/dist/data/designs/ios-things-3-swiftui.md +359 -0
  689. package/dist/data/designs/ios-things-3.md +339 -0
  690. package/dist/data/designs/ios-threads-android.md +588 -0
  691. package/dist/data/designs/ios-threads-expo.md +468 -0
  692. package/dist/data/designs/ios-threads-swiftui.md +452 -0
  693. package/dist/data/designs/ios-threads.md +424 -0
  694. package/dist/data/designs/ios-threema-android.md +496 -0
  695. package/dist/data/designs/ios-threema-expo.md +415 -0
  696. package/dist/data/designs/ios-threema-swiftui.md +446 -0
  697. package/dist/data/designs/ios-threema.md +397 -0
  698. package/dist/data/designs/ios-tidal-android.md +398 -0
  699. package/dist/data/designs/ios-tidal-expo.md +323 -0
  700. package/dist/data/designs/ios-tidal-swiftui.md +340 -0
  701. package/dist/data/designs/ios-tidal.md +351 -0
  702. package/dist/data/designs/ios-tiktok-android.md +654 -0
  703. package/dist/data/designs/ios-tiktok-expo.md +578 -0
  704. package/dist/data/designs/ios-tiktok-swiftui.md +595 -0
  705. package/dist/data/designs/ios-tiktok.md +387 -0
  706. package/dist/data/designs/ios-tinder-android.md +681 -0
  707. package/dist/data/designs/ios-tinder-expo.md +512 -0
  708. package/dist/data/designs/ios-tinder-swiftui.md +497 -0
  709. package/dist/data/designs/ios-tinder.md +415 -0
  710. package/dist/data/designs/ios-todoist-android.md +711 -0
  711. package/dist/data/designs/ios-todoist-expo.md +607 -0
  712. package/dist/data/designs/ios-todoist-swiftui.md +573 -0
  713. package/dist/data/designs/ios-todoist.md +418 -0
  714. package/dist/data/designs/ios-trello-android.md +412 -0
  715. package/dist/data/designs/ios-trello-expo.md +332 -0
  716. package/dist/data/designs/ios-trello-swiftui.md +359 -0
  717. package/dist/data/designs/ios-trello.md +344 -0
  718. package/dist/data/designs/ios-tripadvisor-android.md +450 -0
  719. package/dist/data/designs/ios-tripadvisor-expo.md +322 -0
  720. package/dist/data/designs/ios-tripadvisor-swiftui.md +326 -0
  721. package/dist/data/designs/ios-tripadvisor.md +356 -0
  722. package/dist/data/designs/ios-tubi-android.md +453 -0
  723. package/dist/data/designs/ios-tubi-expo.md +419 -0
  724. package/dist/data/designs/ios-tubi-swiftui.md +463 -0
  725. package/dist/data/designs/ios-tubi.md +383 -0
  726. package/dist/data/designs/ios-tumblr-android.md +462 -0
  727. package/dist/data/designs/ios-tumblr-expo.md +374 -0
  728. package/dist/data/designs/ios-tumblr-swiftui.md +380 -0
  729. package/dist/data/designs/ios-tumblr.md +337 -0
  730. package/dist/data/designs/ios-turo-android.md +500 -0
  731. package/dist/data/designs/ios-turo-expo.md +454 -0
  732. package/dist/data/designs/ios-turo-swiftui.md +447 -0
  733. package/dist/data/designs/ios-turo.md +392 -0
  734. package/dist/data/designs/ios-twitch-android.md +412 -0
  735. package/dist/data/designs/ios-twitch-expo.md +342 -0
  736. package/dist/data/designs/ios-twitch-swiftui.md +328 -0
  737. package/dist/data/designs/ios-twitch.md +354 -0
  738. package/dist/data/designs/ios-uber-android.md +637 -0
  739. package/dist/data/designs/ios-uber-eats-android.md +502 -0
  740. package/dist/data/designs/ios-uber-eats-expo.md +407 -0
  741. package/dist/data/designs/ios-uber-eats-swiftui.md +393 -0
  742. package/dist/data/designs/ios-uber-eats.md +353 -0
  743. package/dist/data/designs/ios-uber-expo.md +512 -0
  744. package/dist/data/designs/ios-uber-swiftui.md +483 -0
  745. package/dist/data/designs/ios-uber.md +395 -0
  746. package/dist/data/designs/ios-united-airlines-android.md +494 -0
  747. package/dist/data/designs/ios-united-airlines-expo.md +408 -0
  748. package/dist/data/designs/ios-united-airlines-swiftui.md +453 -0
  749. package/dist/data/designs/ios-united-airlines.md +388 -0
  750. package/dist/data/designs/ios-venmo-android.md +654 -0
  751. package/dist/data/designs/ios-venmo-expo.md +458 -0
  752. package/dist/data/designs/ios-venmo-swiftui.md +469 -0
  753. package/dist/data/designs/ios-venmo.md +436 -0
  754. package/dist/data/designs/ios-vercel-android.md +454 -0
  755. package/dist/data/designs/ios-vercel-expo.md +387 -0
  756. package/dist/data/designs/ios-vercel-swiftui.md +374 -0
  757. package/dist/data/designs/ios-vercel.md +399 -0
  758. package/dist/data/designs/ios-vero-android.md +498 -0
  759. package/dist/data/designs/ios-vero-expo.md +376 -0
  760. package/dist/data/designs/ios-vero-swiftui.md +374 -0
  761. package/dist/data/designs/ios-vero.md +394 -0
  762. package/dist/data/designs/ios-viber-android.md +377 -0
  763. package/dist/data/designs/ios-viber-expo.md +375 -0
  764. package/dist/data/designs/ios-viber-swiftui.md +378 -0
  765. package/dist/data/designs/ios-viber.md +403 -0
  766. package/dist/data/designs/ios-vimeo-android.md +465 -0
  767. package/dist/data/designs/ios-vimeo-expo.md +347 -0
  768. package/dist/data/designs/ios-vimeo-swiftui.md +383 -0
  769. package/dist/data/designs/ios-vimeo.md +403 -0
  770. package/dist/data/designs/ios-vrbo-android.md +488 -0
  771. package/dist/data/designs/ios-vrbo-expo.md +395 -0
  772. package/dist/data/designs/ios-vrbo-swiftui.md +421 -0
  773. package/dist/data/designs/ios-vrbo.md +383 -0
  774. package/dist/data/designs/ios-vsco-android.md +490 -0
  775. package/dist/data/designs/ios-vsco-expo.md +413 -0
  776. package/dist/data/designs/ios-vsco-swiftui.md +449 -0
  777. package/dist/data/designs/ios-vsco.md +412 -0
  778. package/dist/data/designs/ios-walmart-android.md +479 -0
  779. package/dist/data/designs/ios-walmart-expo.md +370 -0
  780. package/dist/data/designs/ios-walmart-swiftui.md +387 -0
  781. package/dist/data/designs/ios-walmart.md +366 -0
  782. package/dist/data/designs/ios-waze-android.md +695 -0
  783. package/dist/data/designs/ios-waze-expo.md +587 -0
  784. package/dist/data/designs/ios-waze-swiftui.md +601 -0
  785. package/dist/data/designs/ios-waze.md +453 -0
  786. package/dist/data/designs/ios-webull-android.md +429 -0
  787. package/dist/data/designs/ios-webull-expo.md +384 -0
  788. package/dist/data/designs/ios-webull-swiftui.md +406 -0
  789. package/dist/data/designs/ios-webull.md +375 -0
  790. package/dist/data/designs/ios-wechat-android.md +545 -0
  791. package/dist/data/designs/ios-wechat-expo.md +398 -0
  792. package/dist/data/designs/ios-wechat-swiftui.md +394 -0
  793. package/dist/data/designs/ios-wechat.md +363 -0
  794. package/dist/data/designs/ios-whatsapp-android.md +568 -0
  795. package/dist/data/designs/ios-whatsapp-expo.md +502 -0
  796. package/dist/data/designs/ios-whatsapp-swiftui.md +483 -0
  797. package/dist/data/designs/ios-whatsapp.md +425 -0
  798. package/dist/data/designs/ios-whoop-android.md +635 -0
  799. package/dist/data/designs/ios-whoop-expo.md +562 -0
  800. package/dist/data/designs/ios-whoop-swiftui.md +553 -0
  801. package/dist/data/designs/ios-whoop.md +419 -0
  802. package/dist/data/designs/ios-wise-android.md +428 -0
  803. package/dist/data/designs/ios-wise-expo.md +357 -0
  804. package/dist/data/designs/ios-wise-swiftui.md +356 -0
  805. package/dist/data/designs/ios-wise.md +361 -0
  806. package/dist/data/designs/ios-x-twitter-android.md +618 -0
  807. package/dist/data/designs/ios-x-twitter-expo.md +442 -0
  808. package/dist/data/designs/ios-x-twitter-swiftui.md +429 -0
  809. package/dist/data/designs/ios-x-twitter.md +432 -0
  810. package/dist/data/designs/ios-yelp-android.md +455 -0
  811. package/dist/data/designs/ios-yelp-expo.md +397 -0
  812. package/dist/data/designs/ios-yelp-swiftui.md +369 -0
  813. package/dist/data/designs/ios-yelp.md +398 -0
  814. package/dist/data/designs/ios-youtube-android.md +668 -0
  815. package/dist/data/designs/ios-youtube-expo.md +435 -0
  816. package/dist/data/designs/ios-youtube-music-android.md +450 -0
  817. package/dist/data/designs/ios-youtube-music-expo.md +404 -0
  818. package/dist/data/designs/ios-youtube-music-swiftui.md +434 -0
  819. package/dist/data/designs/ios-youtube-music.md +381 -0
  820. package/dist/data/designs/ios-youtube-swiftui.md +496 -0
  821. package/dist/data/designs/ios-youtube.md +466 -0
  822. package/dist/data/designs/ios-zalo-android.md +510 -0
  823. package/dist/data/designs/ios-zalo-expo.md +389 -0
  824. package/dist/data/designs/ios-zalo-swiftui.md +431 -0
  825. package/dist/data/designs/ios-zalo.md +388 -0
  826. package/dist/data/designs/ios-zomato-android.md +527 -0
  827. package/dist/data/designs/ios-zomato-expo.md +437 -0
  828. package/dist/data/designs/ios-zomato-swiftui.md +433 -0
  829. package/dist/data/designs/ios-zomato.md +439 -0
  830. package/dist/data/designs/ios-zoom-android.md +423 -0
  831. package/dist/data/designs/ios-zoom-expo.md +355 -0
  832. package/dist/data/designs/ios-zoom-swiftui.md +379 -0
  833. package/dist/data/designs/ios-zoom.md +357 -0
  834. package/dist/data/designs/ios-zwift-android.md +402 -0
  835. package/dist/data/designs/ios-zwift-expo.md +402 -0
  836. package/dist/data/designs/ios-zwift-swiftui.md +378 -0
  837. package/dist/data/designs/ios-zwift.md +411 -0
  838. package/dist/data/designs/kraken.md +125 -0
  839. package/dist/data/designs/lamborghini.md +288 -0
  840. package/dist/data/designs/linear.app.md +548 -0
  841. package/dist/data/designs/lovable.md +298 -0
  842. package/dist/data/designs/mastercard.md +365 -0
  843. package/dist/data/designs/material-clean.md +289 -0
  844. package/dist/data/designs/meta.md +683 -0
  845. package/dist/data/designs/midnight-pro.md +256 -0
  846. package/dist/data/designs/minimal-brutalist.md +245 -0
  847. package/dist/data/designs/minimax.md +746 -0
  848. package/dist/data/designs/mintlify.md +852 -0
  849. package/dist/data/designs/miro.md +825 -0
  850. package/dist/data/designs/mistral.ai.md +773 -0
  851. package/dist/data/designs/mongodb.md +767 -0
  852. package/dist/data/designs/nike.md +575 -0
  853. package/dist/data/designs/nintendo-2001.md +649 -0
  854. package/dist/data/designs/notion.md +821 -0
  855. package/dist/data/designs/nova-mobile-design-md.md +235 -0
  856. package/dist/data/designs/nvidia.md +640 -0
  857. package/dist/data/designs/ollama.md +539 -0
  858. package/dist/data/designs/opencode.ai.md +521 -0
  859. package/dist/data/designs/pinterest.md +597 -0
  860. package/dist/data/designs/playful-color.md +253 -0
  861. package/dist/data/designs/playstation.md +661 -0
  862. package/dist/data/designs/posthog.md +690 -0
  863. package/dist/data/designs/raycast.md +669 -0
  864. package/dist/data/designs/renault.md +589 -0
  865. package/dist/data/designs/replicate.md +616 -0
  866. package/dist/data/designs/resend.md +585 -0
  867. package/dist/data/designs/revolut.md +636 -0
  868. package/dist/data/designs/runwayml.md +244 -0
  869. package/dist/data/designs/sanity.md +357 -0
  870. package/dist/data/designs/sentry.md +551 -0
  871. package/dist/data/designs/shopify.md +516 -0
  872. package/dist/data/designs/slack.md +482 -0
  873. package/dist/data/designs/soft-glass.md +258 -0
  874. package/dist/data/designs/spacex.md +363 -0
  875. package/dist/data/designs/spotify.md +246 -0
  876. package/dist/data/designs/starbucks.md +580 -0
  877. package/dist/data/designs/stripe.md +487 -0
  878. package/dist/data/designs/supabase.md +462 -0
  879. package/dist/data/designs/superhuman.md +448 -0
  880. package/dist/data/designs/tesla.md +286 -0
  881. package/dist/data/designs/theverge.md +339 -0
  882. package/dist/data/designs/together.ai.md +633 -0
  883. package/dist/data/designs/uber.md +636 -0
  884. package/dist/data/designs/vercel.md +736 -0
  885. package/dist/data/designs/vodafone.md +538 -0
  886. package/dist/data/designs/voltagent.md +521 -0
  887. package/dist/data/designs/warp.md +526 -0
  888. package/dist/data/designs/webflow.md +588 -0
  889. package/dist/data/designs/wired.md +497 -0
  890. package/dist/data/designs/wise.md +544 -0
  891. package/dist/data/designs/x.ai.md +465 -0
  892. package/dist/data/designs/zapier.md +537 -0
  893. package/dist/data/index.json +2600 -0
  894. package/dist/httpServer.js +83 -0
  895. package/dist/index.js +13 -0
  896. package/dist/server.js +32 -0
  897. package/dist/services/designStore.js +59 -0
  898. package/dist/services/linter.js +87 -0
  899. package/dist/services/sectionParser.js +154 -0
  900. package/dist/tools/authoring.js +131 -0
  901. package/dist/tools/browse.js +232 -0
  902. package/dist/tools/diff.js +88 -0
  903. package/dist/tools/getDesign.js +216 -0
  904. package/dist/tools/guardrails.js +87 -0
  905. package/dist/tools/lint.js +104 -0
  906. package/dist/types.js +1 -0
  907. package/package.json +65 -0
@@ -0,0 +1,617 @@
1
+ # Apple Wallet (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports Wallet's visual language to **Android with Jetpack Compose (Material 3)**: a color token object, a `Typography` set, paste-ready `@Composable`s, `Modifier`s, the signature card-stack physics, and haptics.
4
+
5
+ > Why a Compose guide for an iOS-referenced app? The DESIGN.md tokens are platform-neutral. This file keeps the *visual* identity (Wallet's true-black canvas, 80dp card-peek stack, 10dp universal radius, titanium Apple Card) while making everything idiomatic Android — a `Box` Z-stack instead of `matchedGeometryEffect`, `SharedTransitionLayout` for the expand, translucent `Surface` instead of `.regularMaterial`, `sp`/`dp` instead of `pt`. Wallet has no tab bar, so there is no `NavigationBar` here.
6
+
7
+ Assumes Compose BOM `2024.09+`, Kotlin `2.0+`, `minSdk 24`, Material 3, and [Coil](https://coil-kt.github.io/coil/) `2.6+` for issuer card artwork / merchant logos. No color extraction, so no `androidx.palette`.
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/WalletColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+
15
+ object WalletColors {
16
+ // Canvas & Surfaces
17
+ val Canvas = Color(0xFF000000) // true black — NOT system #1C1C1E, so cards float
18
+ val Surface1 = Color(0xFF1C1C1E) // expanded-card supplementary section
19
+ val Surface2 = Color(0xFF2C2C2E) // pressed states, inset rows, scrub track
20
+ val Glass = Color(0x1FFFFFFF) // rgba(255,255,255,0.12) — "+" button, toolbar buttons
21
+ val Hairline = Color(0xFF262629) // separator lines in detail sheets
22
+
23
+ // Text
24
+ val TextPrimary = Color(0xFFFFFFFF)
25
+ val TextSecondary = Color(0xFFA0A0A5)
26
+ val TextTertiary = Color(0xFF636368)
27
+
28
+ // Apple Card titanium (the signature object)
29
+ val TitaniumHi = Color(0xFFE8E8EB) // top-left of 135° gradient
30
+ val TitaniumMid = Color(0xFFA8A8AD) // center
31
+ val TitaniumLo = Color(0xFF3D3D3F) // bottom-right
32
+ val LogoWhite = Color(0xFFFFFFFF) // glyph
33
+ val ChipGold = Color(0xFFC7AC73) // embossed chip
34
+ val DailyCash = Color(0xFFFF3B30) // Daily Cash $ chip
35
+
36
+ // Semantic (HIG dark-mode tints)
37
+ val SystemBlue = Color(0xFF0A84FF) // "See All Transactions" links
38
+ val Success = Color(0xFF30D158) // payment successful
39
+ val Warning = Color(0xFFFF9F0A) // low transit balance
40
+ val Error = Color(0xFFFF453A) // declined card
41
+
42
+ // Common card brand hints (issuer-controlled, recognizable)
43
+ val ChaseBlue = Color(0xFF1A2D4F)
44
+ val AmexSilver = Color(0xFFA7B0B7)
45
+ val VisaNavy = Color(0xFF1A1F71)
46
+ val MastercardR = Color(0xFFEB001B)
47
+ val MastercardO = Color(0xFFFF5F00)
48
+ }
49
+ ```
50
+
51
+ Wire it into a Material 3 `darkColorScheme`. Wallet **is** dark mode — it ignores Light Mode entirely because the cards depend on the true-black canvas — so do not provide a light scheme.
52
+
53
+ ```kotlin
54
+ // ui/theme/Theme.kt
55
+ import androidx.compose.material3.darkColorScheme
56
+ import androidx.compose.material3.MaterialTheme
57
+
58
+ private val WalletScheme = darkColorScheme(
59
+ primary = WalletColors.SystemBlue, // HIG link blue is the only "accent"
60
+ onPrimary = WalletColors.TextPrimary,
61
+ background = WalletColors.Canvas, // true black, not surfaceDim
62
+ onBackground = WalletColors.TextPrimary,
63
+ surface = WalletColors.Surface1,
64
+ onSurface = WalletColors.TextPrimary,
65
+ surfaceVariant = WalletColors.Surface2,
66
+ outline = WalletColors.Hairline,
67
+ error = WalletColors.Error,
68
+ )
69
+
70
+ @Composable
71
+ fun WalletTheme(content: @Composable () -> Unit) =
72
+ MaterialTheme(colorScheme = WalletScheme, typography = WalletTypography, content = content)
73
+ ```
74
+
75
+ ## 2. Typography
76
+
77
+ Wallet's frame is pure SF Pro (Display ≥20pt, Text ≤17pt) — Apple's documented switchover, applied rigidly. SF Pro is proprietary; drop the TTFs in `res/font/` (lowercase, snake_case). Roboto is the closest free Android substitute. The masked card number is the only SF Mono usage — fall back to Roboto Mono / system monospace.
78
+
79
+ ```kotlin
80
+ // ui/theme/WalletType.kt
81
+ import androidx.compose.material3.Typography
82
+ import androidx.compose.ui.text.TextStyle
83
+ import androidx.compose.ui.text.font.Font
84
+ import androidx.compose.ui.text.font.FontFamily
85
+ import androidx.compose.ui.text.font.FontWeight
86
+ import androidx.compose.ui.unit.sp
87
+
88
+ val SFProDisplay = FontFamily(
89
+ Font(R.font.sf_pro_display_regular, FontWeight.Normal), // 400
90
+ Font(R.font.sf_pro_display_medium, FontWeight.Medium), // 500
91
+ Font(R.font.sf_pro_display_semibold, FontWeight.SemiBold), // 600
92
+ Font(R.font.sf_pro_display_bold, FontWeight.Bold), // 700
93
+ )
94
+ val SFProText = FontFamily(
95
+ Font(R.font.sf_pro_text_regular, FontWeight.Normal),
96
+ Font(R.font.sf_pro_text_medium, FontWeight.Medium),
97
+ Font(R.font.sf_pro_text_semibold, FontWeight.SemiBold),
98
+ )
99
+ val SFMono = FontFamily(Font(R.font.sf_mono_medium, FontWeight.Medium)) // card last4 only
100
+
101
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1, same weights/tracking)
102
+ object WalletText {
103
+ val Title = TextStyle(SFProDisplay, fontWeight = FontWeight.Bold, fontSize = 34.sp, lineHeight = 37.sp, letterSpacing = 0.36.sp)
104
+ val SheetTitle = TextStyle(SFProDisplay, fontWeight = FontWeight.Bold, fontSize = 28.sp, lineHeight = 32.sp, letterSpacing = 0.35.sp)
105
+ val SectionHeader = TextStyle(SFProText, fontWeight = FontWeight.SemiBold, fontSize = 13.sp, lineHeight = 16.sp, letterSpacing = (-0.08).sp) // UPPERCASE
106
+ val CardIssuer = TextStyle(SFProDisplay, fontWeight = FontWeight.SemiBold, fontSize = 17.sp, lineHeight = 19.sp)
107
+ val CardLast4 = TextStyle(SFMono, fontWeight = FontWeight.Medium, fontSize = 17.sp, lineHeight = 17.sp, letterSpacing = 0.5.sp)
108
+ val CardHolder = TextStyle(SFProText, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 13.sp, letterSpacing = 0.3.sp)
109
+ val BalanceHero = TextStyle(SFProDisplay, fontWeight = FontWeight.Bold, fontSize = 40.sp, lineHeight = 40.sp, letterSpacing = 0.4.sp)
110
+ val Body = TextStyle(SFProText, fontWeight = FontWeight.Normal, fontSize = 17.sp, lineHeight = 22.sp, letterSpacing = (-0.4).sp)
111
+ val Footnote = TextStyle(SFProText, fontWeight = FontWeight.Normal, fontSize = 13.sp, lineHeight = 17.sp, letterSpacing = (-0.08).sp)
112
+ val Caption = TextStyle(SFProText, fontWeight = FontWeight.Normal, fontSize = 11.sp, lineHeight = 13.sp, letterSpacing = 0.07.sp)
113
+ val TxnAmount = TextStyle(SFProText, fontWeight = FontWeight.Medium, fontSize = 17.sp, lineHeight = 17.sp)
114
+ val DailyCash = TextStyle(SFProDisplay, fontWeight = FontWeight.Bold, fontSize = 22.sp, lineHeight = 22.sp)
115
+ val Action = TextStyle(SFProText, fontWeight = FontWeight.SemiBold, fontSize = 17.sp, lineHeight = 17.sp, letterSpacing = (-0.4).sp)
116
+ }
117
+
118
+ // Map onto Material 3 slots so stock components inherit the system look
119
+ val WalletTypography = Typography(
120
+ headlineLarge = WalletText.Title,
121
+ headlineSmall = WalletText.SheetTitle,
122
+ titleMedium = WalletText.CardIssuer,
123
+ bodyMedium = WalletText.Body,
124
+ labelSmall = WalletText.Caption,
125
+ )
126
+ ```
127
+
128
+ Wallet puts numerals everywhere money appears. Pin tabular figures on every balance/amount/last4 with `TextStyle(fontFeatureSettings = "tnum")` so dollar columns align — apply it to `BalanceHero`, `TxnAmount`, `DailyCash`, `CardLast4`.
129
+
130
+ ## 3. Signature Components
131
+
132
+ ### Apple Card (the signature object)
133
+
134
+ ```kotlin
135
+ import androidx.compose.foundation.background
136
+ import androidx.compose.foundation.layout.*
137
+ import androidx.compose.foundation.shape.RoundedCornerShape
138
+ import androidx.compose.material.icons.Icons
139
+ import androidx.compose.material3.Icon
140
+ import androidx.compose.material3.Text
141
+ import androidx.compose.runtime.Composable
142
+ import androidx.compose.ui.Alignment
143
+ import androidx.compose.ui.Modifier
144
+ import androidx.compose.ui.draw.clip
145
+ import androidx.compose.ui.draw.shadow
146
+ import androidx.compose.ui.geometry.Offset
147
+ import androidx.compose.ui.graphics.Brush
148
+ import androidx.compose.ui.graphics.Color
149
+ import androidx.compose.ui.unit.dp
150
+
151
+ private val CardRadius = RoundedCornerShape(10.dp) // Wallet's universal radius — every card type
152
+
153
+ @Composable
154
+ fun AppleCardFace(
155
+ cardholder: String,
156
+ dailyCashBalance: String,
157
+ modifier: Modifier = Modifier,
158
+ ) {
159
+ Box(
160
+ modifier = modifier
161
+ .fillMaxWidth()
162
+ .height(220.dp)
163
+ .shadow(24.dp, CardRadius, spotColor = Color.Black.copy(alpha = 0.5f)) // heavy — black canvas
164
+ .clip(CardRadius)
165
+ .background(
166
+ Brush.linearGradient( // 135° titanium fade
167
+ colors = listOf(WalletColors.TitaniumHi, WalletColors.TitaniumMid, WalletColors.TitaniumLo),
168
+ start = Offset(0f, 0f),
169
+ end = Offset(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY),
170
+ )
171
+ ),
172
+ ) {
173
+ // 0.5dp inner top highlight — paper-thin glass edge
174
+ Box(
175
+ Modifier.fillMaxWidth().height(0.5.dp).align(Alignment.TopCenter)
176
+ .background(Color.White.copy(alpha = 0.08f))
177
+ )
178
+ Column(Modifier.fillMaxSize().padding(16.dp)) {
179
+ Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.Top) {
180
+ Box(Modifier.size(26.dp, 20.dp).clip(RoundedCornerShape(4.dp)).background(WalletColors.ChipGold))
181
+ Spacer(Modifier.weight(1f))
182
+ Text("", color = WalletColors.LogoWhite, style = WalletText.CardIssuer) // glyph
183
+ }
184
+ Spacer(Modifier.weight(1f))
185
+ Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.Bottom) {
186
+ Text(cardholder.uppercase(), style = WalletText.CardHolder, color = Color(0xFF1A1A1A))
187
+ Spacer(Modifier.weight(1f))
188
+ Box(
189
+ Modifier.size(28.dp).clip(androidx.compose.foundation.shape.CircleShape)
190
+ .background(WalletColors.DailyCash),
191
+ contentAlignment = Alignment.Center,
192
+ ) { Text("$", color = Color.White, style = WalletText.CardIssuer) }
193
+ }
194
+ }
195
+ }
196
+ }
197
+ ```
198
+
199
+ ### Standard Credit/Debit Card
200
+
201
+ ```kotlin
202
+ @Composable
203
+ fun CreditCardFace(
204
+ issuer: String,
205
+ last4: String,
206
+ cardholder: String,
207
+ networkLogoRes: Int, // R.drawable.visa / mastercard / amex
208
+ background: Brush, // issuer-controlled, e.g. Chase Sapphire blue gradient
209
+ modifier: Modifier = Modifier,
210
+ ) {
211
+ Box(
212
+ modifier = modifier
213
+ .fillMaxWidth()
214
+ .height(220.dp)
215
+ .shadow(24.dp, CardRadius, spotColor = Color.Black.copy(alpha = 0.5f))
216
+ .clip(CardRadius)
217
+ .background(background),
218
+ ) {
219
+ Box(
220
+ Modifier.fillMaxWidth().height(0.5.dp).align(Alignment.TopCenter)
221
+ .background(Color.White.copy(alpha = 0.08f))
222
+ )
223
+ Column(Modifier.fillMaxSize().padding(16.dp)) {
224
+ Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.Top) {
225
+ Text(issuer, style = WalletText.CardIssuer, color = Color.White)
226
+ Spacer(Modifier.weight(1f))
227
+ androidx.compose.foundation.Image(
228
+ painter = androidx.compose.ui.res.painterResource(networkLogoRes),
229
+ contentDescription = null,
230
+ modifier = Modifier.height(22.dp),
231
+ )
232
+ }
233
+ Spacer(Modifier.weight(1f))
234
+ Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.Bottom) {
235
+ Text(cardholder.uppercase(), style = WalletText.CardHolder, color = Color.White.copy(alpha = 0.9f))
236
+ Spacer(Modifier.weight(1f))
237
+ Text("•••• $last4", style = WalletText.CardLast4, color = Color.White)
238
+ }
239
+ }
240
+ }
241
+ }
242
+ ```
243
+
244
+ ### Card Stack (the home screen — the hero interaction)
245
+
246
+ A vertical Z-stack: each card offsets `index * 80.dp` down so only an 80dp peek of each shows. Tap → that card animates to full size while the rest tuck down; supplementary content cross-fades in at +200ms. There is no recycler — a typical user has 4–8 cards, so a plain `Column`/`Box` in a `verticalScroll` is correct.
247
+
248
+ ```kotlin
249
+ import androidx.compose.animation.AnimatedVisibility
250
+ import androidx.compose.animation.core.Spring
251
+ import androidx.compose.animation.core.animateDpAsState
252
+ import androidx.compose.animation.core.spring
253
+ import androidx.compose.animation.fadeIn
254
+ import androidx.compose.foundation.clickable
255
+ import androidx.compose.foundation.interaction.MutableInteractionSource
256
+ import androidx.compose.foundation.rememberScrollState
257
+ import androidx.compose.foundation.verticalScroll
258
+ import androidx.compose.runtime.*
259
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
260
+ import androidx.compose.ui.platform.LocalHapticFeedback
261
+
262
+ private const val PEEK = 80 // dp — Wallet's sacred stack interval
263
+
264
+ @Composable
265
+ fun CardStack(
266
+ cards: List<@Composable (expanded: Boolean) -> Unit>,
267
+ modifier: Modifier = Modifier,
268
+ ) {
269
+ var expanded by remember { mutableStateOf<Int?>(null) }
270
+ val haptics = LocalHapticFeedback.current
271
+
272
+ Box(
273
+ modifier
274
+ .fillMaxSize()
275
+ .background(WalletColors.Canvas)
276
+ .verticalScroll(rememberScrollState()),
277
+ ) {
278
+ cards.forEachIndexed { idx, card ->
279
+ val isExpanded = expanded == idx
280
+ val collapsed = expanded == null
281
+ if (collapsed || isExpanded) {
282
+ // Spring: response 0.5 / damping 0.8 → bouncy but contained
283
+ val y by animateDpAsState(
284
+ targetValue = if (collapsed) (idx * PEEK).dp else 0.dp,
285
+ animationSpec = spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMediumLow),
286
+ label = "cardOffset$idx",
287
+ )
288
+ Column(
289
+ Modifier
290
+ .padding(horizontal = 16.dp) // cards never touch the screen edge
291
+ .offset(y = y)
292
+ .clickable(
293
+ interactionSource = remember { MutableInteractionSource() },
294
+ indication = null,
295
+ ) {
296
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ≈ .impact(.medium)
297
+ expanded = if (collapsed) idx else null
298
+ },
299
+ ) {
300
+ card(isExpanded)
301
+ AnimatedVisibility(visible = isExpanded, enter = fadeIn(tween(250, delayMillis = 200))) {
302
+ ExpandedCardDetail() // transactions + balance + toolbar
303
+ }
304
+ }
305
+ }
306
+ }
307
+ }
308
+ }
309
+ ```
310
+
311
+ ### Wallet Home (title + add button + stack)
312
+
313
+ Wallet has **no tab bar** — only the large title and a 32dp circular "+". Render directly, no `Scaffold` bottom bar.
314
+
315
+ ```kotlin
316
+ @Composable
317
+ fun WalletHome(cards: List<@Composable (Boolean) -> Unit>) {
318
+ Column(
319
+ Modifier.fillMaxSize().background(WalletColors.Canvas)
320
+ .windowInsetsPadding(WindowInsets.systemBars),
321
+ ) {
322
+ Row(
323
+ Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
324
+ verticalAlignment = Alignment.CenterVertically,
325
+ ) {
326
+ Text("Wallet", style = WalletText.Title, color = WalletColors.TextPrimary)
327
+ Spacer(Modifier.weight(1f))
328
+ AddCardButton(onClick = { /* open Add Card sheet */ })
329
+ }
330
+ CardStack(cards)
331
+ }
332
+ }
333
+
334
+ @Composable
335
+ fun AddCardButton(onClick: () -> Unit) {
336
+ val haptics = LocalHapticFeedback.current
337
+ Box(
338
+ Modifier
339
+ .size(48.dp) // 44dp+ tap target around a 32dp visual
340
+ .clickable(
341
+ interactionSource = remember { MutableInteractionSource() },
342
+ indication = null,
343
+ ) { haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove); onClick() },
344
+ contentAlignment = Alignment.Center,
345
+ ) {
346
+ Box(
347
+ Modifier.size(32.dp).clip(androidx.compose.foundation.shape.CircleShape)
348
+ .background(WalletColors.Glass),
349
+ contentAlignment = Alignment.Center,
350
+ ) {
351
+ Icon(Icons.Filled.Add, contentDescription = "Add card", tint = WalletColors.TextPrimary,
352
+ modifier = Modifier.size(16.dp))
353
+ }
354
+ }
355
+ }
356
+ ```
357
+
358
+ ### Transaction Row
359
+
360
+ ```kotlin
361
+ import androidx.compose.material.icons.filled.ShoppingCart
362
+
363
+ @Composable
364
+ fun TransactionRow(
365
+ merchant: String,
366
+ date: String,
367
+ amount: String,
368
+ dailyCash: String?,
369
+ modifier: Modifier = Modifier,
370
+ ) {
371
+ Box(modifier.fillMaxWidth().background(WalletColors.Surface1)) {
372
+ Row(
373
+ Modifier.fillMaxWidth().height(60.dp).padding(horizontal = 16.dp),
374
+ verticalAlignment = Alignment.CenterVertically,
375
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
376
+ ) {
377
+ Box(
378
+ Modifier.size(32.dp).clip(androidx.compose.foundation.shape.CircleShape)
379
+ .background(WalletColors.Surface2),
380
+ contentAlignment = Alignment.Center,
381
+ ) {
382
+ Icon(Icons.Filled.ShoppingCart, contentDescription = null,
383
+ tint = WalletColors.TextPrimary, modifier = Modifier.size(14.dp))
384
+ }
385
+ Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(2.dp)) {
386
+ Text(merchant, style = WalletText.Body, color = WalletColors.TextPrimary, maxLines = 1)
387
+ Text(date, style = WalletText.Footnote, color = WalletColors.TextSecondary, maxLines = 1)
388
+ }
389
+ Column(horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.spacedBy(2.dp)) {
390
+ Text(amount, style = WalletText.TxnAmount, color = WalletColors.TextPrimary)
391
+ if (dailyCash != null) {
392
+ Text("Daily Cash $dailyCash", style = WalletText.Caption, color = WalletColors.DailyCash)
393
+ }
394
+ }
395
+ }
396
+ Box(
397
+ Modifier.align(Alignment.BottomStart).padding(start = 16.dp)
398
+ .fillMaxWidth().height(0.5.dp).background(WalletColors.Hairline)
399
+ )
400
+ }
401
+ }
402
+ ```
403
+
404
+ ### Action Toolbar (bottom of an expanded card)
405
+
406
+ iOS uses `.regularMaterial`; Android has no first-class live blur, so use a 92%-opaque true-black `Surface`. Three 44dp circular glass buttons.
407
+
408
+ ```kotlin
409
+ import androidx.compose.material.icons.filled.CreditCard
410
+ import androidx.compose.material.icons.filled.MoreHoriz
411
+ import androidx.compose.material.icons.automirrored.filled.ListAlt
412
+ import androidx.compose.material3.Surface
413
+ import androidx.compose.ui.graphics.vector.ImageVector
414
+
415
+ @Composable
416
+ fun ActionToolbar() {
417
+ Surface(color = WalletColors.Canvas.copy(alpha = 0.92f)) { // ≈ .regularMaterial over #000
418
+ Box {
419
+ Box(Modifier.fillMaxWidth().height(0.5.dp).background(WalletColors.Hairline))
420
+ Row(
421
+ Modifier.fillMaxWidth().height(56.dp).padding(horizontal = 16.dp),
422
+ horizontalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterHorizontally),
423
+ verticalAlignment = Alignment.CenterVertically,
424
+ ) {
425
+ ToolbarButton(Icons.Filled.CreditCard, "Card details")
426
+ ToolbarButton(Icons.AutoMirrored.Filled.ListAlt, "Transactions")
427
+ ToolbarButton(Icons.Filled.MoreHoriz, "More")
428
+ }
429
+ }
430
+ }
431
+ }
432
+
433
+ @Composable
434
+ private fun ToolbarButton(icon: ImageVector, label: String) {
435
+ val haptics = LocalHapticFeedback.current
436
+ Box(
437
+ Modifier
438
+ .size(44.dp)
439
+ .clip(androidx.compose.foundation.shape.CircleShape)
440
+ .background(WalletColors.Glass)
441
+ .clickable(
442
+ interactionSource = remember { MutableInteractionSource() },
443
+ indication = null,
444
+ ) { haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove) }, // ≈ .selection
445
+ contentAlignment = Alignment.Center,
446
+ ) { Icon(icon, contentDescription = label, tint = WalletColors.TextPrimary, modifier = Modifier.size(18.dp)) }
447
+ }
448
+ ```
449
+
450
+ ### Pay Now Button (Apple Card payment flow)
451
+
452
+ ```kotlin
453
+ @Composable
454
+ fun PayNowButton(onPayNow: () -> Unit, modifier: Modifier = Modifier) {
455
+ val interaction = remember { MutableInteractionSource() }
456
+ val pressed by androidx.compose.foundation.interaction.collectIsPressedAsState(interaction).let { it }
457
+ val haptics = LocalHapticFeedback.current
458
+ Box(
459
+ modifier
460
+ .fillMaxWidth()
461
+ .padding(horizontal = 16.dp)
462
+ .height(54.dp)
463
+ .clip(RoundedCornerShape(14.dp))
464
+ .background(if (pressed) Color(0xFFE5E5E5) else Color.White)
465
+ .clickable(interaction, indication = null) {
466
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress)
467
+ onPayNow()
468
+ },
469
+ contentAlignment = Alignment.Center,
470
+ ) { Text("Pay Now", style = WalletText.Action, color = WalletColors.Canvas) }
471
+ }
472
+ ```
473
+
474
+ ## 4. Apple Pay Invocation (the most distinctive interaction)
475
+
476
+ Wallet has no color extraction; its signature dynamic moment is the Apple Pay handoff: the card slams to center, the screen turns true black, a biometric glyph appears, then a success check with `.notificationOccurred(.success)`. On Android, the OS double-press is replaced by your in-app trigger; `SharedTransitionLayout` (Compose 1.7+) carries the card from the stack into the overlay.
477
+
478
+ ```kotlin
479
+ import androidx.compose.material.icons.filled.CheckCircle
480
+ import androidx.compose.material.icons.filled.Fingerprint
481
+ import kotlinx.coroutines.delay
482
+
483
+ @Composable
484
+ fun ApplePayOverlay(cardArtworkUrl: String, onAuthenticated: () -> Unit) {
485
+ var authenticated by remember { mutableStateOf(false) }
486
+ val haptics = LocalHapticFeedback.current
487
+
488
+ LaunchedEffect(authenticated) {
489
+ if (authenticated) {
490
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ≈ .notification(.success)
491
+ delay(700)
492
+ onAuthenticated()
493
+ }
494
+ }
495
+
496
+ Box(
497
+ Modifier.fillMaxSize().background(WalletColors.Canvas), // screen turns true black
498
+ contentAlignment = Alignment.TopCenter,
499
+ ) {
500
+ Column(
501
+ Modifier.fillMaxSize().padding(top = 64.dp),
502
+ horizontalAlignment = Alignment.CenterHorizontally,
503
+ verticalArrangement = Arrangement.spacedBy(32.dp),
504
+ ) {
505
+ coil.compose.AsyncImage(
506
+ model = cardArtworkUrl,
507
+ contentDescription = "Apple Card",
508
+ modifier = Modifier
509
+ .fillMaxWidth(0.92f)
510
+ .height(220.dp)
511
+ .shadow(24.dp, CardRadius, spotColor = Color.Black.copy(alpha = 0.5f))
512
+ .clip(CardRadius),
513
+ )
514
+ if (!authenticated) {
515
+ Column(
516
+ horizontalAlignment = Alignment.CenterHorizontally,
517
+ verticalArrangement = Arrangement.spacedBy(12.dp),
518
+ ) {
519
+ Icon(Icons.Filled.Fingerprint, contentDescription = null,
520
+ tint = WalletColors.TextPrimary, modifier = Modifier.size(64.dp))
521
+ Text("Confirm with biometrics", style = WalletText.Body, color = WalletColors.TextPrimary)
522
+ }
523
+ LaunchedEffect(Unit) { delay(800); authenticated = true } // demo: BiometricPrompt in prod
524
+ } else {
525
+ Icon(Icons.Filled.CheckCircle, contentDescription = "Confirmed",
526
+ tint = WalletColors.Success, modifier = Modifier.size(64.dp))
527
+ }
528
+ Spacer(Modifier.weight(1f))
529
+ Text("Hold near reader", style = WalletText.SheetTitle, color = WalletColors.TextPrimary,
530
+ modifier = Modifier.padding(bottom = 48.dp))
531
+ }
532
+ }
533
+ }
534
+ ```
535
+
536
+ In production, replace the demo `delay` with `androidx.biometric.BiometricPrompt`; keep the `#000000` background and `WalletColors.Success` check so it reads as the system Apple Pay sheet.
537
+
538
+ ## 5. Navigation
539
+
540
+ Wallet has **no navigation chrome** — no `NavigationBar`, no rail, no `TopAppBar`. The entire app is the card stack and its expanded detail; the only persistent affordances are the "Wallet" title and the 32dp "+" button (see §3 `WalletHome`). Do not add a `Scaffold` `bottomBar`.
541
+
542
+ Detail sheets (Card Details, Settings) rise as Material 3 `ModalBottomSheet` with a 14dp top radius (matching iOS sheet corners) over the true-black canvas. Use a `Surface(color = WalletColors.Surface1)` for grouped lists, with `Hairline` separators inset 16dp from the leading edge. Where iOS uses `.regularMaterial`, use a translucent `Surface` (`WalletColors.Canvas.copy(alpha = 0.92f)`) — Android has no live blur.
543
+
544
+ ```kotlin
545
+ @OptIn(androidx.compose.material3.ExperimentalMaterial3Api::class)
546
+ @Composable
547
+ fun CardDetailSheet(onDismiss: () -> Unit, content: @Composable () -> Unit) {
548
+ androidx.compose.material3.ModalBottomSheet(
549
+ onDismissRequest = onDismiss,
550
+ containerColor = WalletColors.Surface1,
551
+ shape = RoundedCornerShape(topStart = 14.dp, topEnd = 14.dp),
552
+ ) { content() }
553
+ }
554
+ ```
555
+
556
+ ## 6. Motion
557
+
558
+ | Moment | Compose recipe |
559
+ |--------|----------------|
560
+ | Card tap → expand | `animateDpAsState` peek-offset → 0 with `spring(dampingRatio = 0.8f, stiffness = StiffnessMediumLow)` (≈ response 0.5); `HapticFeedbackType.LongPress` (.impact medium) |
561
+ | Card collapse | same spring reversed; release haptic `HapticFeedbackType.TextHandleMove` (≈ .impact soft) |
562
+ | Supplementary content reveal | `AnimatedVisibility` + `fadeIn(tween(250, delayMillis = 200))` below the expanded card |
563
+ | Daily Cash chip pulse | `rememberInfiniteTransition` scale 1.0 → 1.04 → 1.0 over 1200ms, only on the Apple Card face |
564
+ | Transit balance update | `Animatable` scrub old → new over 800ms with `tween(easing = FastOutSlowInEasing)` |
565
+ | Boarding-pass flip | `animateFloatAsState` `rotationY` 0 → 180 over 600ms, `graphicsLayer { rotationY = … }` |
566
+ | Apple Pay success | `HapticFeedbackType.LongPress` then cross-fade to the green check |
567
+
568
+ ```kotlin
569
+ // Daily Cash chip breathing pulse — Apple Card only
570
+ @Composable
571
+ fun DailyCashChip(amount: String) {
572
+ val t = rememberInfiniteTransition(label = "dailyCash")
573
+ val scale by t.animateFloat(
574
+ initialValue = 1f, targetValue = 1.04f,
575
+ animationSpec = infiniteRepeatable(tween(1200), RepeatMode.Reverse),
576
+ label = "pulse",
577
+ )
578
+ Box(
579
+ Modifier
580
+ .size(28.dp)
581
+ .graphicsLayer { scaleX = scale; scaleY = scale }
582
+ .clip(androidx.compose.foundation.shape.CircleShape)
583
+ .background(WalletColors.DailyCash),
584
+ contentAlignment = Alignment.Center,
585
+ ) { Text("$", color = Color.White, style = WalletText.CardIssuer) }
586
+ }
587
+ ```
588
+
589
+ For the mini-bar → expanded card transition prefer `SharedTransitionLayout` + `Modifier.sharedElement()` on the card artwork (Compose 1.7+). Haptics: prefer `LocalHapticFeedback`; for richer control use `LocalView.current.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)` (API 30+) or a `Vibrator` `VibrationEffect.createOneShot(10, ...)` to approximate iOS's `.soft` impact. Honor **Reduce Motion**: when `Settings.Global.ANIMATOR_DURATION_SCALE == 0f`, skip the spring bounce and use a 0.25s linear cross-fade for the card expand.
590
+
591
+ ## 7. Icons
592
+
593
+ Wallet uses a handful of SF Symbols; the closest first-party set is `androidx.compose.material:material-icons-extended`. The Apple logo glyph and brand network marks (Visa/Mastercard/AmEx) have no Material equivalent — ship them as vector drawables and load via `ImageVector.vectorResource(R.drawable.…)`.
594
+
595
+ | Purpose | SF Symbol (iOS) | Material Icon (Compose) |
596
+ |---------|-----------------|--------------------------|
597
+ | Add card "+" | `plus` | `Icons.Filled.Add` |
598
+ | Apple logo | / `applelogo` | custom vector drawable (no Material glyph) |
599
+ | Card details | `creditcard.fill` | `Icons.Filled.CreditCard` |
600
+ | Transactions list | `list.bullet.rectangle` | `Icons.AutoMirrored.Filled.ListAlt` |
601
+ | More menu | `ellipsis` | `Icons.Filled.MoreHoriz` |
602
+ | Disclosure | `chevron.right` | `Icons.AutoMirrored.Filled.KeyboardArrowRight` |
603
+ | Biometric confirm | `faceid` | `Icons.Filled.Fingerprint` (or custom Face Unlock glyph) |
604
+ | Success check | `checkmark.circle.fill` | `Icons.Filled.CheckCircle` |
605
+ | Transit NFC waves | `wave.3.right` | `Icons.Filled.Contactless` |
606
+ | Merchant default | `cart.fill` / `bag.fill` | `Icons.Filled.ShoppingCart` |
607
+ | Card network marks | (brand assets) | custom vector drawables (Visa/Mastercard/AmEx) |
608
+
609
+ ## 8. Minimum SDK & Accessibility Notes
610
+
611
+ - **minSdk 24** (Compose floor is 21; modern motion + `SharedTransitionLayout` comfortable at 24). `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`.
612
+ - **Edge-to-edge**: call `enableEdgeToEdge()` in the `Activity`; the true-black canvas wants `WindowCompat` light-content (white) system-bar icons. Apply `Modifier.windowInsetsPadding(WindowInsets.systemBars)` so the title clears the status bar and the last card keeps 24dp clearance above the gesture-nav indicator.
613
+ - **Font scaling**: `sp` honors the user's font scale automatically — keep it on the Wallet title, detail body, transaction rows. The **card face is artwork, not text** — pin issuer name, last4, holder name, and balance hero so the card never reflows: wrap card composables in `CompositionLocalProvider(LocalDensity provides Density(LocalDensity.current.density, fontScale = 1f))`.
614
+ - **TalkBack**: each card is one accessibility element — `Modifier.semantics(mergeDescendants = true) { contentDescription = "Apple Card, ending in 4521, \$1,284.20 balance, collapsed" }`; update to "expanded" on tap. Mark the toolbar glyphs and "+" as separate buttons with their own labels.
615
+ - **Touch targets**: Material guidance is 48.dp minimum. The 80dp card peek and 54dp Pay Now clear it; the 32dp "+" and 18dp toolbar glyphs are wrapped in 44–48dp hit areas via padding (see §3).
616
+ - **Contrast**: white on the titanium gradient passes WCAG AA at the `#E8E8EB` highlight but is borderline over the `#3D3D3F` shadow end — paint a 30%-black scrim behind any text positioned over the dark end of the gradient. `#A0A0A5` on `#1C1C1E` passes AA at 14sp+; validate the 11sp caption / Daily Cash labels with a contrast checker and bump toward `#B0B0B5` if targeting strict compliance.
617
+ - **Dynamic color**: do **not** enable Material You `dynamicDarkColorScheme()` — Wallet's identity requires the fixed `#000000` canvas and HIG system-blue links regardless of wallpaper. (Material You is right for Google/Material-first apps; Wallet is a strong-brand exception.) Wallet also ignores Light Mode entirely — stay on the dark scheme even when the system is Light, because the floating-card effect depends on true black.