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,611 @@
1
+ # Coinbase (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports Coinbase's visual language to **Android with Jetpack Compose (Material 3)**: a color token object, a `Typography` set, paste-ready `@Composable`s, `Modifier`s, motion, 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 (Coinbase's institutional white canvas, single electric-blue accent, brand-color asset icons, tabular-numeral asset columns) while making everything idiomatic Android — `NavigationBar` instead of a UITabBar, an inline `Canvas` sparkline instead of Swift Charts, `sp`/`dp` instead of `pt`.
6
+
7
+ Assumes Compose BOM `2024.09+`, Kotlin `2.0+`, `minSdk 24`, Material 3, and [Coil](https://coil-kt.github.io/coil/) `2.6+` if you load remote asset artwork (icons here are color circles + glyphs, so Coil is optional).
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/CoinbaseColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+
15
+ object CoinbaseColors {
16
+ // Brand
17
+ val Blue = Color(0xFF0052FF)
18
+ val BluePressed = Color(0xFF0040CC)
19
+ val BlueTint = Color(0xFFE5EDFF)
20
+ val BlueDark = Color(0xFF3B6CFF) // brightened for dark-mode AA
21
+ val Black = Color(0xFF0A0B0D) // Coinbase Black — slight cool tint, NOT pure #000
22
+ val Charcoal = Color(0xFF1A1C1F)
23
+
24
+ // Crypto asset colors (each token's official brand identity)
25
+ val Bitcoin = Color(0xFFF7931A)
26
+ val Ethereum = Color(0xFF627EEA)
27
+ val USDC = Color(0xFF2775CA)
28
+ val Solana = Color(0xFF9945FF)
29
+ val Cardano = Color(0xFF0033AD)
30
+ val Tether = Color(0xFF26A17B)
31
+
32
+ // Canvas & Surfaces (light)
33
+ val Canvas = Color(0xFFFFFFFF)
34
+ val SurfaceGray = Color(0xFFF7F8FA)
35
+ val SurfaceGray2 = Color(0xFFEEF0F3)
36
+ val Divider = Color(0xFFE1E4E8)
37
+
38
+ // Text (light)
39
+ val TextPrimary = Color(0xFF0A0B0D) // Coinbase Black
40
+ val TextSecondary = Color(0xFF5B616E)
41
+ val TextTertiary = Color(0xFF80868F)
42
+ val TextMuted = Color(0xFFA0A4AA)
43
+
44
+ // Semantic — color binds to direction
45
+ val Success = Color(0xFF05B169)
46
+ val SuccessTint = Color(0xFFE6F7EF)
47
+ val Loss = Color(0xFFCF202F)
48
+ val LossTint = Color(0xFFFCE7E9)
49
+ val Warning = Color(0xFFF5A623)
50
+
51
+ // Dark mode
52
+ val DarkCanvas = Color(0xFF0A0B0D)
53
+ val DarkSurface1 = Color(0xFF13151A)
54
+ val DarkSurface2 = Color(0xFF1E2026)
55
+ val DarkDivider = Color(0xFF2A2E36)
56
+ val DarkTextPri = Color(0xFFFFFFFF)
57
+ val DarkTextSec = Color(0xFFA0A4AA)
58
+ }
59
+ ```
60
+
61
+ Coinbase is white-canvas first; wire a `lightColorScheme` and a deep near-black `darkColorScheme`. Coinbase Blue brightens to `#3B6CFF` on dark for AA contrast.
62
+
63
+ ```kotlin
64
+ // ui/theme/Theme.kt
65
+ import androidx.compose.material3.MaterialTheme
66
+ import androidx.compose.material3.darkColorScheme
67
+ import androidx.compose.material3.lightColorScheme
68
+ import androidx.compose.runtime.Composable
69
+
70
+ private val CoinbaseLight = lightColorScheme(
71
+ primary = CoinbaseColors.Blue,
72
+ onPrimary = CoinbaseColors.Canvas,
73
+ background = CoinbaseColors.Canvas,
74
+ onBackground = CoinbaseColors.TextPrimary,
75
+ surface = CoinbaseColors.Canvas,
76
+ onSurface = CoinbaseColors.TextPrimary,
77
+ surfaceVariant = CoinbaseColors.SurfaceGray,
78
+ outline = CoinbaseColors.Divider,
79
+ error = CoinbaseColors.Loss,
80
+ )
81
+
82
+ private val CoinbaseDark = darkColorScheme(
83
+ primary = CoinbaseColors.BlueDark, // AA on dark
84
+ onPrimary = CoinbaseColors.Canvas,
85
+ background = CoinbaseColors.DarkCanvas,
86
+ onBackground = CoinbaseColors.DarkTextPri,
87
+ surface = CoinbaseColors.DarkSurface1,
88
+ onSurface = CoinbaseColors.DarkTextPri,
89
+ surfaceVariant = CoinbaseColors.DarkSurface2,
90
+ outline = CoinbaseColors.DarkDivider,
91
+ error = CoinbaseColors.Loss,
92
+ )
93
+
94
+ @Composable
95
+ fun CoinbaseTheme(useDark: Boolean = false, content: @Composable () -> Unit) =
96
+ MaterialTheme(
97
+ colorScheme = if (useDark) CoinbaseDark else CoinbaseLight,
98
+ typography = CoinbaseTypography,
99
+ content = content,
100
+ )
101
+ ```
102
+
103
+ ## 2. Typography
104
+
105
+ Coinbase Sans / Display / Mono are proprietary (Frere-Jones Type, ~2021). Drop the TTFs in `res/font/` (lowercase, snake_case). Fall back to the system sans for Sans/Display and the system monospace for Mono. Apply `fontFeatureSettings = "tnum"` (tabular figures) on every price, percentage, and quantity — non-negotiable for the institutional column.
106
+
107
+ ```kotlin
108
+ // ui/theme/CoinbaseType.kt
109
+ import androidx.compose.material3.Typography
110
+ import androidx.compose.ui.text.TextStyle
111
+ import androidx.compose.ui.text.font.Font
112
+ import androidx.compose.ui.text.font.FontFamily
113
+ import androidx.compose.ui.text.font.FontWeight
114
+ import androidx.compose.ui.unit.sp
115
+
116
+ val CoinbaseSans = FontFamily(
117
+ Font(R.font.coinbase_sans_regular, FontWeight.Normal),
118
+ Font(R.font.coinbase_sans_medium, FontWeight.Medium),
119
+ Font(R.font.coinbase_sans_semibold, FontWeight.SemiBold),
120
+ Font(R.font.coinbase_sans_bold, FontWeight.Bold),
121
+ )
122
+ val CoinbaseDisplay = FontFamily(
123
+ Font(R.font.coinbase_display_bold, FontWeight.Bold),
124
+ )
125
+ val CoinbaseMono = FontFamily(
126
+ Font(R.font.coinbase_mono_regular, FontWeight.Normal),
127
+ Font(R.font.coinbase_mono_medium, FontWeight.Medium),
128
+ )
129
+
130
+ private const val TNUM = "tnum" // tabular figures — apply to every financial number
131
+
132
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1)
133
+ object CoinbaseText {
134
+ val PortfolioHero = TextStyle(CoinbaseDisplay, fontWeight = FontWeight.Bold, fontSize = 40.sp, lineHeight = 40.sp, letterSpacing = (-0.5).sp, fontFeatureSettings = TNUM)
135
+ val BuyAmount = TextStyle(CoinbaseDisplay, fontWeight = FontWeight.Bold, fontSize = 56.sp, lineHeight = 56.sp, letterSpacing = (-1.0).sp, fontFeatureSettings = TNUM)
136
+ val ScreenTitle = TextStyle(CoinbaseDisplay, fontWeight = FontWeight.Bold, fontSize = 28.sp, lineHeight = 31.sp, letterSpacing = (-0.3).sp)
137
+ val SectionHeader = TextStyle(CoinbaseSans, fontWeight = FontWeight.Bold, fontSize = 20.sp, lineHeight = 23.sp, letterSpacing = (-0.2).sp)
138
+ val AssetTitle = TextStyle(CoinbaseSans, fontWeight = FontWeight.SemiBold, fontSize = 16.sp, lineHeight = 21.sp)
139
+ val Ticker = TextStyle(CoinbaseSans, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 17.sp, letterSpacing = 0.3.sp)
140
+ val AssetPrice = TextStyle(CoinbaseSans, fontWeight = FontWeight.Medium, fontSize = 16.sp, lineHeight = 19.sp, fontFeatureSettings = TNUM)
141
+ val AssetChange = TextStyle(CoinbaseSans, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 17.sp, fontFeatureSettings = TNUM)
142
+ val Body = TextStyle(CoinbaseSans, fontWeight = FontWeight.Normal, fontSize = 15.sp, lineHeight = 22.sp)
143
+ val BodySmall = TextStyle(CoinbaseSans, fontWeight = FontWeight.Normal, fontSize = 13.sp, lineHeight = 18.sp)
144
+ val WalletAddr = TextStyle(CoinbaseMono, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 18.sp)
145
+ val TxHash = TextStyle(CoinbaseMono, fontWeight = FontWeight.Normal, fontSize = 12.sp, lineHeight = 17.sp)
146
+ val Button = TextStyle(CoinbaseSans, fontWeight = FontWeight.SemiBold, fontSize = 16.sp, lineHeight = 16.sp)
147
+ val ButtonSmall = TextStyle(CoinbaseSans, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 13.sp)
148
+ val Tab = TextStyle(CoinbaseSans, fontWeight = FontWeight.SemiBold, fontSize = 10.sp, lineHeight = 10.sp, letterSpacing = 0.1.sp)
149
+ val AllCaps = TextStyle(CoinbaseSans, fontWeight = FontWeight.Bold, fontSize = 11.sp, lineHeight = 13.sp, letterSpacing = 0.6.sp)
150
+ val RangeChip = TextStyle(CoinbaseSans, fontWeight = FontWeight.SemiBold, fontSize = 13.sp, lineHeight = 13.sp, letterSpacing = 0.3.sp)
151
+ }
152
+
153
+ // Map onto Material 3 slots
154
+ val CoinbaseTypography = Typography(
155
+ displayLarge = CoinbaseText.PortfolioHero,
156
+ headlineLarge = CoinbaseText.ScreenTitle,
157
+ titleLarge = CoinbaseText.SectionHeader,
158
+ titleMedium = CoinbaseText.AssetTitle,
159
+ bodyMedium = CoinbaseText.Body,
160
+ labelSmall = CoinbaseText.Tab,
161
+ )
162
+ ```
163
+
164
+ ## 3. Signature Components
165
+
166
+ ### Portfolio Hero
167
+
168
+ ```kotlin
169
+ import androidx.compose.foundation.layout.*
170
+ import androidx.compose.material3.Text
171
+ import androidx.compose.runtime.Composable
172
+ import androidx.compose.ui.Modifier
173
+ import androidx.compose.ui.unit.dp
174
+ import java.text.NumberFormat
175
+ import kotlin.math.abs
176
+
177
+ @Composable
178
+ fun PortfolioHero(
179
+ value: Double,
180
+ dayChange: Double,
181
+ dayChangePct: Double,
182
+ modifier: Modifier = Modifier,
183
+ ) {
184
+ val up = dayChange >= 0
185
+ val sign = if (up) "+" else "−"
186
+ val color = if (up) CoinbaseColors.Success else CoinbaseColors.Loss
187
+ val usd = NumberFormat.getCurrencyInstance()
188
+
189
+ Column(
190
+ modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 16.dp),
191
+ verticalArrangement = Arrangement.spacedBy(8.dp),
192
+ ) {
193
+ Text("PORTFOLIO BALANCE", style = CoinbaseText.AllCaps, color = CoinbaseColors.TextSecondary)
194
+ Text(usd.format(value), style = CoinbaseText.PortfolioHero, color = CoinbaseColors.TextPrimary)
195
+ Text(
196
+ "$sign${usd.format(abs(dayChange))} ($sign${"%.2f".format(abs(dayChangePct * 100))}%)",
197
+ style = CoinbaseText.AssetPrice,
198
+ color = color,
199
+ )
200
+ }
201
+ }
202
+ ```
203
+
204
+ ### Asset Row with Mini Sparkline
205
+
206
+ ```kotlin
207
+ import androidx.compose.foundation.Canvas
208
+ import androidx.compose.foundation.background
209
+ import androidx.compose.foundation.shape.CircleShape
210
+ import androidx.compose.ui.Alignment
211
+ import androidx.compose.ui.draw.clip
212
+ import androidx.compose.ui.geometry.Offset
213
+ import androidx.compose.ui.graphics.Color
214
+ import androidx.compose.ui.graphics.StrokeCap
215
+ import androidx.compose.ui.graphics.drawscope.Stroke
216
+ import androidx.compose.ui.graphics.Path
217
+
218
+ @Composable
219
+ fun AssetRow(
220
+ assetName: String,
221
+ ticker: String,
222
+ holdings: String,
223
+ price: Double,
224
+ dayChangePct: Double,
225
+ iconColor: Color, // CoinbaseColors.Bitcoin, .Ethereum, .USDC …
226
+ glyph: String, // "₿", "Ξ", "$"
227
+ sparkline: List<Float>, // 24h price points
228
+ modifier: Modifier = Modifier,
229
+ ) {
230
+ val up = dayChangePct >= 0
231
+ val dir = if (up) CoinbaseColors.Success else CoinbaseColors.Loss
232
+ val sign = if (up) "+" else "−"
233
+ val usd = NumberFormat.getCurrencyInstance()
234
+
235
+ Row(
236
+ modifier
237
+ .fillMaxWidth()
238
+ .height(64.dp)
239
+ .background(CoinbaseColors.Canvas)
240
+ .padding(horizontal = 16.dp),
241
+ verticalAlignment = Alignment.CenterVertically,
242
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
243
+ ) {
244
+ Box(Modifier.size(40.dp).clip(CircleShape).background(iconColor), contentAlignment = Alignment.Center) {
245
+ Text(glyph, style = CoinbaseText.AssetTitle.copy(fontSize = 18.sp), color = Color.White)
246
+ }
247
+ Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
248
+ Text(assetName, style = CoinbaseText.AssetTitle, color = CoinbaseColors.TextPrimary)
249
+ Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
250
+ Text(ticker, style = CoinbaseText.Ticker, color = CoinbaseColors.TextSecondary)
251
+ Text("· $holdings", style = CoinbaseText.BodySmall, color = CoinbaseColors.TextSecondary)
252
+ }
253
+ }
254
+ Spacer(Modifier.weight(1f))
255
+ MiniSparkline(sparkline, dir, Modifier.size(width = 56.dp, height = 20.dp))
256
+ Column(horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.spacedBy(2.dp)) {
257
+ Text(usd.format(price), style = CoinbaseText.AssetPrice, color = CoinbaseColors.TextPrimary)
258
+ Text("$sign${"%.2f".format(abs(dayChangePct * 100))}%", style = CoinbaseText.AssetChange, color = dir)
259
+ }
260
+ }
261
+ }
262
+
263
+ @Composable
264
+ fun MiniSparkline(points: List<Float>, color: Color, modifier: Modifier = Modifier) {
265
+ Canvas(modifier) {
266
+ if (points.size < 2) return@Canvas
267
+ val min = points.min(); val max = points.max()
268
+ val range = (max - min).takeIf { it > 0f } ?: 1f
269
+ val dx = size.width / (points.size - 1)
270
+ val path = Path()
271
+ points.forEachIndexed { i, p ->
272
+ val x = i * dx
273
+ val y = size.height - ((p - min) / range) * size.height
274
+ if (i == 0) path.moveTo(x, y) else path.lineTo(x, y)
275
+ }
276
+ drawPath(path, color, style = Stroke(width = 1.5.dp.toPx(), cap = StrokeCap.Round))
277
+ }
278
+ }
279
+ ```
280
+
281
+ ### 4-Up Action Row (Buy / Sell / Send / Receive)
282
+
283
+ ```kotlin
284
+ import androidx.compose.foundation.clickable
285
+ import androidx.compose.foundation.interaction.MutableInteractionSource
286
+ import androidx.compose.foundation.shape.RoundedCornerShape
287
+ import androidx.compose.material.icons.Icons
288
+ import androidx.compose.material.icons.filled.ArrowDownward
289
+ import androidx.compose.material.icons.filled.ArrowUpward
290
+ import androidx.compose.material.icons.filled.QrCode
291
+ import androidx.compose.material.icons.filled.Send
292
+ import androidx.compose.material3.Icon
293
+ import androidx.compose.ui.graphics.vector.ImageVector
294
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
295
+ import androidx.compose.ui.platform.LocalHapticFeedback
296
+
297
+ @Composable
298
+ fun AssetActionRow(
299
+ onBuy: () -> Unit, onSell: () -> Unit, onSend: () -> Unit, onReceive: () -> Unit,
300
+ modifier: Modifier = Modifier,
301
+ ) {
302
+ Row(modifier.fillMaxWidth().padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
303
+ ActionButton(Icons.Filled.ArrowUpward, "Buy", onBuy, Modifier.weight(1f))
304
+ ActionButton(Icons.Filled.ArrowDownward, "Sell", onSell, Modifier.weight(1f))
305
+ ActionButton(Icons.Filled.Send, "Send", onSend, Modifier.weight(1f))
306
+ ActionButton(Icons.Filled.QrCode, "Receive", onReceive, Modifier.weight(1f))
307
+ }
308
+ }
309
+
310
+ @Composable
311
+ private fun ActionButton(icon: ImageVector, label: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
312
+ val haptics = LocalHapticFeedback.current
313
+ Column(
314
+ modifier
315
+ .clip(RoundedCornerShape(12.dp))
316
+ .background(CoinbaseColors.SurfaceGray)
317
+ .clickable(remember { MutableInteractionSource() }, indication = null) {
318
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove) // light — these are previews
319
+ onClick()
320
+ }
321
+ .padding(vertical = 16.dp),
322
+ horizontalAlignment = Alignment.CenterHorizontally,
323
+ verticalArrangement = Arrangement.spacedBy(8.dp),
324
+ ) {
325
+ Icon(icon, contentDescription = label, tint = CoinbaseColors.Blue, modifier = Modifier.size(24.dp))
326
+ Text(label, style = CoinbaseText.ButtonSmall, color = CoinbaseColors.TextPrimary)
327
+ }
328
+ }
329
+ ```
330
+
331
+ ### Primary / Secondary CTA
332
+
333
+ ```kotlin
334
+ import androidx.compose.animation.core.animateFloatAsState
335
+ import androidx.compose.animation.core.spring
336
+ import androidx.compose.foundation.interaction.collectIsPressedAsState
337
+ import androidx.compose.ui.draw.scale
338
+
339
+ @Composable
340
+ fun CBPrimaryButton(label: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
341
+ val interaction = remember { MutableInteractionSource() }
342
+ val pressed by interaction.collectIsPressedAsState()
343
+ val scale by animateFloatAsState(if (pressed) 0.98f else 1f, spring(), label = "cta")
344
+ val haptics = LocalHapticFeedback.current
345
+ Box(
346
+ modifier
347
+ .fillMaxWidth()
348
+ .height(48.dp)
349
+ .scale(scale)
350
+ .clip(RoundedCornerShape(12.dp))
351
+ .background(if (pressed) CoinbaseColors.BluePressed else CoinbaseColors.Blue)
352
+ .clickable(interaction, indication = null) {
353
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ~iOS medium on Buy confirm
354
+ onClick()
355
+ },
356
+ contentAlignment = Alignment.Center,
357
+ ) {
358
+ Text(label, style = CoinbaseText.Button, color = Color.White)
359
+ }
360
+ }
361
+
362
+ @Composable
363
+ fun CBSecondaryButton(label: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
364
+ Box(
365
+ modifier
366
+ .fillMaxWidth().height(48.dp)
367
+ .clip(RoundedCornerShape(12.dp))
368
+ .background(CoinbaseColors.SurfaceGray2)
369
+ .clickable(onClick = onClick),
370
+ contentAlignment = Alignment.Center,
371
+ ) {
372
+ Text(label, style = CoinbaseText.Button, color = CoinbaseColors.TextPrimary)
373
+ }
374
+ }
375
+ ```
376
+
377
+ ### Coinbase C-Mark Logomark
378
+
379
+ A perfect circle with a horizontal line through it — always Coinbase Blue, always geometric.
380
+
381
+ ```kotlin
382
+ @Composable
383
+ fun CoinbaseCMark(size: androidx.compose.ui.unit.Dp = 28.dp, color: Color = CoinbaseColors.Blue, modifier: Modifier = Modifier) {
384
+ Canvas(modifier.size(size)) {
385
+ val stroke = this.size.minDimension * 0.18f
386
+ drawCircle(color, radius = (this.size.minDimension - stroke) / 2f, style = Stroke(width = stroke))
387
+ val barW = this.size.width * 0.42f
388
+ val barH = this.size.height * 0.16f
389
+ drawRect(
390
+ color,
391
+ topLeft = Offset((this.size.width - barW) / 2f, (this.size.height - barH) / 2f),
392
+ size = androidx.compose.ui.geometry.Size(barW, barH),
393
+ )
394
+ }
395
+ }
396
+
397
+ // Loading variant — slow 1500ms rotation
398
+ @Composable
399
+ fun CoinbaseCMarkLoading(modifier: Modifier = Modifier) {
400
+ val t = rememberInfiniteTransition(label = "cmark")
401
+ val deg by t.animateFloat(0f, 360f, infiniteRepeatable(tween(1500, easing = LinearEasing)), label = "rot")
402
+ CoinbaseCMark(modifier = modifier.rotate(deg))
403
+ }
404
+ ```
405
+
406
+ ### Wallet Address Display (Mono — never proportional Sans)
407
+
408
+ ```kotlin
409
+ import androidx.compose.material.icons.filled.Check
410
+ import androidx.compose.material.icons.filled.ContentCopy
411
+ import androidx.compose.ui.platform.LocalClipboardManager
412
+ import androidx.compose.ui.text.AnnotatedString
413
+ import kotlinx.coroutines.delay
414
+
415
+ @Composable
416
+ fun WalletAddressView(address: String, modifier: Modifier = Modifier) {
417
+ var copied by remember { mutableStateOf(false) }
418
+ val clipboard = LocalClipboardManager.current
419
+ val haptics = LocalHapticFeedback.current
420
+ val truncated = if (address.length > 14) "${address.take(10)}...${address.takeLast(8)}" else address
421
+ LaunchedEffect(copied) { if (copied) { delay(1500); copied = false } }
422
+
423
+ Row(
424
+ modifier
425
+ .fillMaxWidth()
426
+ .clip(RoundedCornerShape(8.dp))
427
+ .background(CoinbaseColors.SurfaceGray)
428
+ .clickable {
429
+ clipboard.setText(AnnotatedString(address))
430
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress)
431
+ copied = true
432
+ }
433
+ .padding(12.dp),
434
+ verticalAlignment = Alignment.CenterVertically,
435
+ ) {
436
+ Text(truncated, style = CoinbaseText.WalletAddr, color = CoinbaseColors.TextPrimary)
437
+ Spacer(Modifier.weight(1f))
438
+ Icon(
439
+ if (copied) Icons.Filled.Check else Icons.Filled.ContentCopy,
440
+ contentDescription = "Copy address",
441
+ tint = if (copied) CoinbaseColors.Success else CoinbaseColors.TextSecondary,
442
+ modifier = Modifier.size(20.dp),
443
+ )
444
+ }
445
+ }
446
+ ```
447
+
448
+ ## 4. Portfolio Chart with Scrubber (the signature dynamic)
449
+
450
+ Coinbase has no color extraction — its distinctive dynamic system is the **full-bleed 2dp portfolio line with a finger-tracking scrubber that morphs the hero value in real time**. Build the line on `Canvas`; drag updates the highlighted price via numeric morph (`animateFloatAsState` with a snappy spring on the hero value).
451
+
452
+ ```kotlin
453
+ import androidx.compose.foundation.gestures.detectDragGestures
454
+ import androidx.compose.ui.input.pointer.pointerInput
455
+ import kotlin.math.roundToInt
456
+
457
+ @Composable
458
+ fun PortfolioChart(
459
+ points: List<Float>, // price series for the selected range
460
+ up: Boolean,
461
+ onScrub: (price: Float?) -> Unit, // null when finger lifts → restore live value
462
+ modifier: Modifier = Modifier,
463
+ ) {
464
+ val line = if (up) CoinbaseColors.Success else CoinbaseColors.Loss
465
+ var scrubX by remember { mutableStateOf<Float?>(null) }
466
+
467
+ Canvas(
468
+ modifier
469
+ .fillMaxWidth()
470
+ .height(180.dp)
471
+ .pointerInput(points) {
472
+ detectDragGestures(
473
+ onDragStart = { scrubX = it.x },
474
+ onDrag = { change, _ -> scrubX = change.position.x.coerceIn(0f, size.width.toFloat()) },
475
+ onDragEnd = { scrubX = null; onScrub(null) },
476
+ )
477
+ },
478
+ ) {
479
+ if (points.size < 2) return@Canvas
480
+ val min = points.min(); val max = points.max()
481
+ val range = (max - min).takeIf { it > 0f } ?: 1f
482
+ val dx = size.width / (points.size - 1)
483
+ val path = Path()
484
+ points.forEachIndexed { i, p ->
485
+ val x = i * dx
486
+ val y = size.height - ((p - min) / range) * size.height
487
+ if (i == 0) path.moveTo(x, y) else path.lineTo(x, y)
488
+ }
489
+ drawPath(path, line, style = Stroke(width = 2.dp.toPx(), cap = StrokeCap.Round))
490
+
491
+ scrubX?.let { sx ->
492
+ val idx = (sx / dx).roundToInt().coerceIn(0, points.lastIndex)
493
+ onScrub(points[idx]) // hero value morphs to this; no fill below the line — Coinbase style
494
+ drawLine(CoinbaseColors.Divider, Offset(sx, 0f), Offset(sx, size.height), strokeWidth = 1.dp.toPx())
495
+ }
496
+ }
497
+ }
498
+
499
+ // Hoist the live value; the hero recomposes with a numeric morph during scrubbing:
500
+ // val display by animateFloatAsState(scrubbed ?: liveValue, animationSpec = spring(stiffness = 900f), label = "hero")
501
+ ```
502
+
503
+ Range chips below the chart (`1H / 1D / 1W / 1M / 1Y / ALL`): transparent default, `SurfaceGray2` selected, text `TextSecondary` → `TextPrimary` when active, 8dp corners.
504
+
505
+ ## 5. Navigation
506
+
507
+ Coinbase uses a **5-tab bottom bar** (Home / Trade / Cards / Earn / Wallet). iOS uses an opaque white tab bar — Android has no live blur, so use an opaque `Canvas`-white `NavigationBar` with a hairline top divider. Active tint is Coinbase Blue.
508
+
509
+ ```kotlin
510
+ import androidx.compose.material.icons.filled.CreditCard
511
+ import androidx.compose.material.icons.filled.Home
512
+ import androidx.compose.material.icons.filled.Percent
513
+ import androidx.compose.material.icons.filled.SwapHoriz
514
+ import androidx.compose.material.icons.filled.Wallet
515
+ import androidx.compose.material3.NavigationBar
516
+ import androidx.compose.material3.NavigationBarItem
517
+ import androidx.compose.material3.NavigationBarItemDefaults
518
+
519
+ @Composable
520
+ fun CoinbaseBottomBar(selected: Int, onSelect: (Int) -> Unit) {
521
+ NavigationBar(containerColor = CoinbaseColors.Canvas, tonalElevation = 0.dp) {
522
+ val items = listOf(
523
+ "Home" to Icons.Filled.Home,
524
+ "Trade" to Icons.Filled.SwapHoriz,
525
+ "Cards" to Icons.Filled.CreditCard,
526
+ "Earn" to Icons.Filled.Percent,
527
+ "Wallet" to Icons.Filled.Wallet,
528
+ )
529
+ val haptics = LocalHapticFeedback.current
530
+ items.forEachIndexed { i, (label, icon) ->
531
+ NavigationBarItem(
532
+ selected = selected == i,
533
+ onClick = {
534
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove) // ~iOS .selectionChanged
535
+ onSelect(i)
536
+ },
537
+ icon = { Icon(icon, contentDescription = label, modifier = Modifier.size(24.dp)) },
538
+ label = { Text(label, style = CoinbaseText.Tab) },
539
+ colors = NavigationBarItemDefaults.colors(
540
+ selectedIconColor = CoinbaseColors.Blue,
541
+ selectedTextColor = CoinbaseColors.Blue,
542
+ unselectedIconColor = CoinbaseColors.TextSecondary,
543
+ unselectedTextColor = CoinbaseColors.TextSecondary,
544
+ indicatorColor = CoinbaseColors.BlueTint,
545
+ ),
546
+ )
547
+ }
548
+ }
549
+ }
550
+ ```
551
+
552
+ ## 6. Motion
553
+
554
+ | Moment | Compose recipe |
555
+ |--------|----------------|
556
+ | Buy/Sell tap | `animateFloatAsState` 1 → 0.98 with `spring(stiffness ≈ 600f)`; `HapticFeedbackType.LongPress` (~iOS medium) |
557
+ | Order placed | success modal slides up 350ms; checkmark `scale` 0.5 → 1.0 spring delayed 100ms; success haptic |
558
+ | Chart scrubber drag | instant `detectDragGestures` (no spring on the line); hero value numeric morph via `animateFloatAsState(spring(stiffness = 900f))` |
559
+ | Asset row tap | background fade `Canvas` → `SurfaceGray` over 150ms before navigating |
560
+ | Tab switch | icon swap + label color `TextSecondary` → `Blue` over 200ms; `HapticFeedbackType.TextHandleMove` |
561
+ | C-mark loading | `rememberInfiniteTransition` `rotate` 0 → 360 over 1500ms, `LinearEasing` |
562
+ | Wallet copy | 1500ms `Success` toast at top — no confetti |
563
+
564
+ ```kotlin
565
+ // Order-confirmation checkmark scale-in
566
+ val scale by animateFloatAsState(
567
+ targetValue = if (showCheck) 1f else 0.5f,
568
+ animationSpec = spring(dampingRatio = 0.7f, stiffness = 380f),
569
+ label = "check",
570
+ )
571
+ Icon(Icons.Filled.CheckCircle, null, tint = CoinbaseColors.Success, modifier = Modifier.scale(scale))
572
+ ```
573
+
574
+ Haptics: prefer `LocalHapticFeedback`. For richer control use `LocalView.current.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)` (API 30+) or `Vibrator` `VibrationEffect.createOneShot(...)` for the order-success notification feel.
575
+
576
+ ## 7. Icons
577
+
578
+ Coinbase ships a geometric C-mark (drawn on `Canvas` in §3) and per-token asset glyphs. The rest map to `androidx.compose.material:material-icons-extended`; ship custom token glyphs as vector drawables.
579
+
580
+ | Component | SF Symbol (iOS) | Material Icon (Compose) |
581
+ |-----------|-----------------|--------------------------|
582
+ | Home tab | `house` | `Icons.Filled.Home` |
583
+ | Trade tab | `arrow.left.arrow.right` | `Icons.Filled.SwapHoriz` |
584
+ | Cards tab | `creditcard` | `Icons.Filled.CreditCard` |
585
+ | Earn tab | `percent` | `Icons.Filled.Percent` |
586
+ | Wallet tab | `wallet.pass` | `Icons.Filled.Wallet` |
587
+ | 4-up Buy | `arrow.up` | `Icons.Filled.ArrowUpward` |
588
+ | 4-up Sell | `arrow.down` | `Icons.Filled.ArrowDownward` |
589
+ | 4-up Send | `paperplane` | `Icons.Filled.Send` |
590
+ | 4-up Receive | `qrcode` | `Icons.Filled.QrCode` |
591
+ | Search | `magnifyingglass` | `Icons.Filled.Search` |
592
+ | Notifications | `bell` | `Icons.Filled.Notifications` |
593
+ | Watchlist | `star` / `star.fill` | `Icons.Outlined.StarBorder` / `Icons.Filled.Star` |
594
+ | Back | `chevron.left` | `Icons.Filled.ChevronLeft` |
595
+ | Share | `square.and.arrow.up` | `Icons.Filled.IosShare` |
596
+ | Success | `checkmark.circle.fill` | `Icons.Filled.CheckCircle` |
597
+ | Pending | `clock.fill` | `Icons.Filled.Schedule` |
598
+ | Copy | `doc.on.doc` | `Icons.Filled.ContentCopy` |
599
+ | C-mark | (custom) | Custom `Canvas` `CoinbaseCMark` — always geometric |
600
+
601
+ ## 8. Minimum SDK & Accessibility Notes
602
+
603
+ - **minSdk 24** (Compose floor is 21; modern motion is comfortable at 24). `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`.
604
+ - **Edge-to-edge**: call `enableEdgeToEdge()` in the `Activity`. White canvas wants dark-content system bars (`isAppearanceLightStatusBars = true`); apply `Scaffold` insets so the tab bar and sticky Buy/Sell footer clear gesture nav.
605
+ - **Tabular figures**: every price, percentage, and quantity must carry `fontFeatureSettings = "tnum"` (baked into `CoinbaseText.AssetPrice` / `AssetChange` / `PortfolioHero`) so the asset list aligns into the institutional column.
606
+ - **Font scaling**: `sp` honors the user's font scale — keep it on body, asset titles, secondary labels. Pin layout-sensitive text (tab labels, range chips, Mono addresses). Portfolio hero (40sp) scales but cap at 56sp; Buy/Sell entry (56sp) cap at 72sp; asset price scales to 20sp max.
607
+ - **TalkBack**: merge the asset row into one node — `Modifier.semantics(mergeDescendants = true) { contentDescription = "Bitcoin, B T C, you own 0.1842, price $67,234.18, up 1.92 percent today" }`. Portfolio hero: announce balance + change. Expand the truncated wallet address to the full string for the announcement.
608
+ - **Touch targets**: Material guidance is 48dp minimum. Asset row is 64dp (clear); the 24dp tab icons sit in 48dp+ `NavigationBarItem` slots; ensure range chips and the copy glyph reach 48dp hit area via padding.
609
+ - **Contrast**: `#0A0B0D` on white exceeds WCAG AAA; Coinbase Blue `#0052FF` on white clears AAA. The real low-contrast pairs are **`#80868F` TextTertiary on white** and **`#A0A4AA` TextMuted on white** — validate at 11sp tab/all-caps labels and darken toward `#5B616E` if targeting compliance. Pair green/red with directional `+`/`−` and sparkline shape when `differentiateWithoutColor` is set.
610
+ - **Reduce motion**: when `Settings.Global.ANIMATOR_DURATION_SCALE == 0f`, skip the hero numeric morph during scrubbing and the C-mark rotation (crossfade instead).
611
+ - **Dynamic color**: do **not** enable Material You `dynamicLightColorScheme()` — Coinbase's brand requires the fixed `#0052FF` electric blue regardless of wallpaper. Strong-brand app: keep the curated scheme.