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,587 @@
1
+ # Robinhood (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports Robinhood'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 (the stark white canvas with true-black text, direction-bound green/orange, the full-bleed portfolio chart with its draggable scrubber, tabular numerals everywhere) while making everything idiomatic Android — a `Canvas`-drawn line graph with `pointerInput` scrubbing instead of Swift `Charts`, `NavigationBar` instead of a UITabBar, `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+` for fetched company/ticker logos.
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/RobinhoodColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+
15
+ object RobinhoodColors {
16
+ // Canvas & Surfaces (Light)
17
+ val CanvasLight = Color(0xFFFFFFFF)
18
+ val SurfaceGray = Color(0xFFF7F7F7)
19
+ val SurfaceGray2 = Color(0xFFEFEFEF)
20
+ val DividerLight = Color(0xFFE6E6E6)
21
+
22
+ // Text (Light) — true black, no warm grays
23
+ val TextPrimary = Color(0xFF000000)
24
+ val TextSecondary = Color(0xFF5C6166)
25
+ val TextTertiary = Color(0xFF9B9EA3)
26
+ val TextMuted = Color(0xFFC2C5CA)
27
+
28
+ // Brand — color is bound to direction
29
+ val Green = Color(0xFF00C805) // up
30
+ val GreenPressed = Color(0xFF00A904)
31
+ val GreenDim = Color(0xFF21CE99) // heritage
32
+ val GreenBg = Color(0xFFE6F9E0)
33
+ val Red = Color(0xFFFF5000) // down — a saturated ORANGE, not red
34
+ val RedBg = Color(0xFFFFEDE5)
35
+
36
+ // Semantic
37
+ val ErrorTrue = Color(0xFFE62232) // a TRUE red — hard errors only, distinct from loss orange
38
+ val Warning = Color(0xFFFFB800)
39
+ val Info = Color(0xFF1D6FF2)
40
+
41
+ // Crypto accents
42
+ val Bitcoin = Color(0xFFF7931A)
43
+ val Ethereum = Color(0xFF627EEA)
44
+
45
+ // Dark mode — true black; the green line glows electric
46
+ val DarkCanvas = Color(0xFF000000)
47
+ val DarkSurface1 = Color(0xFF181B1F)
48
+ val DarkSurface2 = Color(0xFF23272D)
49
+ val DarkDivider = Color(0xFF2D3138)
50
+ val DarkTextPrimary = Color(0xFFFFFFFF)
51
+ val DarkTextSecondary = Color(0xFFA4A8AD)
52
+ }
53
+ ```
54
+
55
+ Robinhood's default is a **stark light canvas** — clean tech-product, deliberate counterpoint to legacy brokerages. Wire a Material 3 `lightColorScheme`/`darkColorScheme`. **Do not map green/orange onto `primary`/`error`** — they are *direction* signals, not theme roles. Keep `primary` as black (the universal Trade CTA color) and the brand greens/orange as explicit tokens so no stock component can accidentally use them.
56
+
57
+ ```kotlin
58
+ // ui/theme/Theme.kt
59
+ import androidx.compose.material3.*
60
+ import androidx.compose.runtime.Composable
61
+ import androidx.compose.foundation.isSystemInDarkTheme
62
+
63
+ private val RobinhoodLight = lightColorScheme(
64
+ primary = RobinhoodColors.TextPrimary, // black — the universal Trade CTA
65
+ onPrimary = Color.White,
66
+ background = RobinhoodColors.CanvasLight,
67
+ onBackground = RobinhoodColors.TextPrimary,
68
+ surface = RobinhoodColors.CanvasLight,
69
+ onSurface = RobinhoodColors.TextPrimary,
70
+ surfaceVariant = RobinhoodColors.SurfaceGray,
71
+ outline = RobinhoodColors.DividerLight,
72
+ error = RobinhoodColors.ErrorTrue, // the TRUE red, not the loss orange
73
+ )
74
+
75
+ private val RobinhoodDark = darkColorScheme(
76
+ primary = RobinhoodColors.DarkTextPrimary, // white — Trade CTA on black
77
+ onPrimary = RobinhoodColors.DarkCanvas,
78
+ background = RobinhoodColors.DarkCanvas,
79
+ onBackground = RobinhoodColors.DarkTextPrimary,
80
+ surface = RobinhoodColors.DarkSurface1,
81
+ onSurface = RobinhoodColors.DarkTextPrimary,
82
+ surfaceVariant = RobinhoodColors.DarkSurface2,
83
+ outline = RobinhoodColors.DarkDivider,
84
+ error = RobinhoodColors.ErrorTrue,
85
+ )
86
+
87
+ @Composable
88
+ fun RobinhoodTheme(
89
+ dark: Boolean = isSystemInDarkTheme(),
90
+ content: @Composable () -> Unit,
91
+ ) = MaterialTheme(
92
+ colorScheme = if (dark) RobinhoodDark else RobinhoodLight,
93
+ typography = RobinhoodTypography,
94
+ content = content,
95
+ )
96
+ ```
97
+
98
+ ## 2. Typography
99
+
100
+ Capsule Sans (drawn by XYZ Type for Robinhood) is proprietary. Drop the TTFs in `res/font/` and build two families — `CapsuleSansText` for body, `CapsuleSansDisplay` for hero values. Fall back to the system font; on the fallback, **always** apply `FontFeatureSettings("tnum")` (tabular numerals) — this is the single most important typography rule on a brokerage app: columns of prices must align as the user scrolls.
101
+
102
+ ```kotlin
103
+ // ui/theme/RobinhoodType.kt
104
+ import androidx.compose.material3.Typography
105
+ import androidx.compose.ui.text.TextStyle
106
+ import androidx.compose.ui.text.font.Font
107
+ import androidx.compose.ui.text.font.FontFamily
108
+ import androidx.compose.ui.text.font.FontWeight
109
+ import androidx.compose.ui.unit.sp
110
+
111
+ val CapsuleText = FontFamily(
112
+ Font(R.font.capsule_sans_text_regular, FontWeight.Normal), // 400
113
+ Font(R.font.capsule_sans_text_medium, FontWeight.Medium), // 500
114
+ Font(R.font.capsule_sans_text_semibold, FontWeight.SemiBold), // 600
115
+ Font(R.font.capsule_sans_text_bold, FontWeight.Bold), // 700
116
+ )
117
+ val CapsuleDisplay = FontFamily(
118
+ Font(R.font.capsule_sans_display_bold, FontWeight.Bold), // hero values 40sp+
119
+ )
120
+
121
+ // Tabular numerals — non-negotiable on every price / percent / share count
122
+ private const val TNUM = "tnum"
123
+
124
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1)
125
+ object RobinhoodText {
126
+ val PortfolioHero = TextStyle(CapsuleDisplay, fontWeight = FontWeight.Bold, fontSize = 40.sp, lineHeight = 40.sp, letterSpacing = (-0.5).sp, fontFeatureSettings = TNUM)
127
+ val DayChange = TextStyle(CapsuleText, fontWeight = FontWeight.Medium, fontSize = 16.sp, lineHeight = 19.sp, fontFeatureSettings = TNUM)
128
+ val ScreenTitle = TextStyle(CapsuleText, fontWeight = FontWeight.Bold, fontSize = 22.sp, lineHeight = 25.sp, letterSpacing = (-0.2).sp)
129
+ val SectionHeader = TextStyle(CapsuleText, fontWeight = FontWeight.SemiBold, fontSize = 18.sp, lineHeight = 22.sp, letterSpacing = (-0.1).sp)
130
+ val PositionTitle = TextStyle(CapsuleText, fontWeight = FontWeight.SemiBold, fontSize = 16.sp, lineHeight = 21.sp)
131
+ val Ticker = TextStyle(CapsuleText, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 17.sp, letterSpacing = 0.3.sp)
132
+ val PositionValue = TextStyle(CapsuleText, fontWeight = FontWeight.Medium, fontSize = 17.sp, lineHeight = 20.sp, fontFeatureSettings = TNUM)
133
+ val PositionChange = TextStyle(CapsuleText, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 17.sp, fontFeatureSettings = TNUM)
134
+ val ChartAxis = TextStyle(CapsuleText, fontWeight = FontWeight.Medium, fontSize = 11.sp, lineHeight = 11.sp, letterSpacing = 0.2.sp, fontFeatureSettings = TNUM)
135
+ val Body = TextStyle(CapsuleText, fontWeight = FontWeight.Normal, fontSize = 15.sp, lineHeight = 21.sp)
136
+ val BodySmall = TextStyle(CapsuleText, fontWeight = FontWeight.Normal, fontSize = 13.sp, lineHeight = 18.sp)
137
+ val ButtonPrimary = TextStyle(CapsuleText, fontWeight = FontWeight.SemiBold, fontSize = 16.sp, lineHeight = 16.sp)
138
+ val RangeChip = TextStyle(CapsuleText, fontWeight = FontWeight.SemiBold, fontSize = 13.sp, lineHeight = 13.sp, letterSpacing = 0.3.sp)
139
+ val TabLabel = TextStyle(CapsuleText, fontWeight = FontWeight.SemiBold, fontSize = 10.sp, lineHeight = 10.sp, letterSpacing = 0.2.sp)
140
+ val AllCaps = TextStyle(CapsuleText, fontWeight = FontWeight.Bold, fontSize = 11.sp, lineHeight = 13.sp, letterSpacing = 0.6.sp)
141
+ }
142
+
143
+ val RobinhoodTypography = Typography(
144
+ displayMedium = RobinhoodText.PortfolioHero,
145
+ headlineSmall = RobinhoodText.ScreenTitle,
146
+ titleMedium = RobinhoodText.PositionTitle,
147
+ bodyMedium = RobinhoodText.Body,
148
+ labelSmall = RobinhoodText.TabLabel,
149
+ )
150
+ ```
151
+
152
+ ## 3. Signature Components
153
+
154
+ ### Portfolio Hero (top of Investing tab)
155
+
156
+ `BUYING POWER` all-caps label → the giant tabular `$` value in Capsule Display → the day-change line in green (up) or orange (down) — no pill chrome, just colored text. The value morphs in <100ms during chart scrubbing.
157
+
158
+ ```kotlin
159
+ import androidx.compose.animation.AnimatedContent
160
+ import androidx.compose.animation.core.tween
161
+ import androidx.compose.animation.fadeIn
162
+ import androidx.compose.animation.fadeOut
163
+ import androidx.compose.animation.togetherWith
164
+ import androidx.compose.foundation.layout.*
165
+ import androidx.compose.material3.Text
166
+ import androidx.compose.runtime.Composable
167
+ import androidx.compose.ui.Modifier
168
+ import androidx.compose.ui.unit.dp
169
+ import java.text.NumberFormat
170
+ import java.util.Locale
171
+
172
+ private val usd = NumberFormat.getCurrencyInstance(Locale.US)
173
+
174
+ @Composable
175
+ fun PortfolioHero(
176
+ portfolioValue: Double,
177
+ dayChange: Double,
178
+ dayChangePct: Double,
179
+ modifier: Modifier = Modifier,
180
+ ) {
181
+ val up = dayChange >= 0
182
+ val changeColor = if (up) RobinhoodColors.Green else RobinhoodColors.Red
183
+ val sign = if (up) "+" else "−"
184
+
185
+ Column(
186
+ modifier = modifier
187
+ .fillMaxWidth()
188
+ .padding(horizontal = 24.dp, vertical = 16.dp),
189
+ verticalArrangement = Arrangement.spacedBy(8.dp),
190
+ ) {
191
+ Text("BUYING POWER", style = RobinhoodText.AllCaps, color = RobinhoodColors.TextSecondary)
192
+ // Value morphs during scrub
193
+ AnimatedContent(
194
+ targetState = portfolioValue,
195
+ transitionSpec = { (fadeIn(tween(90)) togetherWith fadeOut(tween(90))) },
196
+ label = "portfolioValue",
197
+ ) { v ->
198
+ Text(usd.format(v), style = RobinhoodText.PortfolioHero, color = RobinhoodColors.TextPrimary)
199
+ }
200
+ Text(
201
+ "$sign${usd.format(kotlin.math.abs(dayChange))} ($sign${"%.2f".format(dayChangePct * 100)}%) Today",
202
+ style = RobinhoodText.DayChange,
203
+ color = changeColor,
204
+ )
205
+ }
206
+ }
207
+ ```
208
+
209
+ ### Portfolio Chart with Scrubber (THE Robinhood interaction)
210
+
211
+ Swift `Charts` has no Compose equivalent that supports the live scrubber idiomatically — draw it with `Canvas` and capture the drag with `pointerInput`. A 2.dp stroke in the day's color, **no fill below the line**, full-bleed. Dragging snaps the bubble to the nearest data point and drives the hero value (hoist `scrubValue` to the screen and feed it back into `PortfolioHero`).
212
+
213
+ ```kotlin
214
+ import androidx.compose.foundation.Canvas
215
+ import androidx.compose.foundation.gestures.detectDragGestures
216
+ import androidx.compose.runtime.*
217
+ import androidx.compose.ui.geometry.Offset
218
+ import androidx.compose.ui.graphics.Path
219
+ import androidx.compose.ui.graphics.drawscope.Stroke
220
+ import androidx.compose.ui.input.pointer.pointerInput
221
+ import androidx.compose.ui.platform.LocalHapticFeedback
222
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
223
+
224
+ @Composable
225
+ fun PortfolioChart(
226
+ points: List<Float>, // y-values, evenly spaced in x
227
+ isUp: Boolean,
228
+ onScrub: (index: Int?) -> Unit, // null on release → hero snaps back to current
229
+ modifier: Modifier = Modifier,
230
+ ) {
231
+ val lineColor = if (isUp) RobinhoodColors.Green else RobinhoodColors.Red
232
+ var activeIndex by remember { mutableStateOf<Int?>(null) }
233
+ val haptics = LocalHapticFeedback.current
234
+ val strokePx = with(androidx.compose.ui.platform.LocalDensity.current) { 2.dp.toPx() }
235
+
236
+ Canvas(
237
+ modifier = modifier
238
+ .fillMaxWidth()
239
+ .height(220.dp) // 180 on small phones, 240 on Max — derive from windowSizeClass
240
+ .pointerInput(points) {
241
+ detectDragGestures(
242
+ onDragStart = { off ->
243
+ val idx = ((off.x / size.width) * (points.size - 1)).toInt().coerceIn(points.indices)
244
+ activeIndex = idx; onScrub(idx)
245
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove)
246
+ },
247
+ onDrag = { change, _ ->
248
+ val idx = ((change.position.x / size.width) * (points.size - 1)).toInt().coerceIn(points.indices)
249
+ if (idx != activeIndex) {
250
+ activeIndex = idx; onScrub(idx) // instant — no smoothing
251
+ }
252
+ },
253
+ onDragEnd = { activeIndex = null; onScrub(null) },
254
+ onDragCancel = { activeIndex = null; onScrub(null) },
255
+ )
256
+ },
257
+ ) {
258
+ if (points.size < 2) return@Canvas
259
+ val maxV = points.max(); val minV = points.min()
260
+ val range = (maxV - minV).takeIf { it != 0f } ?: 1f
261
+ fun px(i: Int) = size.width * i / (points.size - 1)
262
+ fun py(v: Float) = size.height * (1f - (v - minV) / range)
263
+
264
+ val path = Path().apply {
265
+ moveTo(px(0), py(points[0]))
266
+ for (i in 1 until points.size) lineTo(px(i), py(points[i]))
267
+ }
268
+ drawPath(path, color = lineColor, style = Stroke(width = strokePx)) // no fill below
269
+
270
+ activeIndex?.let { i ->
271
+ // thin vertical rule + solid black point bubble
272
+ drawLine(RobinhoodColors.TextPrimary, Offset(px(i), 0f), Offset(px(i), size.height), strokeWidth = 1f)
273
+ drawCircle(RobinhoodColors.TextPrimary, radius = 8f, center = Offset(px(i), py(points[i])))
274
+ }
275
+ }
276
+ }
277
+ ```
278
+
279
+ ### Chart Range Chips
280
+
281
+ Text-only, no container. Active flips to the chart-line color with a 2.dp underline.
282
+
283
+ ```kotlin
284
+ import androidx.compose.foundation.background
285
+ import androidx.compose.foundation.layout.Box
286
+
287
+ @Composable
288
+ fun ChartRangeChips(
289
+ selected: String,
290
+ isUp: Boolean,
291
+ onSelect: (String) -> Unit,
292
+ modifier: Modifier = Modifier,
293
+ ) {
294
+ val active = if (isUp) RobinhoodColors.Green else RobinhoodColors.Red
295
+ val ranges = listOf("1D", "1W", "1M", "3M", "YTD", "1Y", "5Y", "ALL")
296
+ val haptics = LocalHapticFeedback.current
297
+
298
+ Row(
299
+ modifier = modifier.fillMaxWidth().padding(horizontal = 16.dp),
300
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
301
+ ) {
302
+ ranges.forEach { r ->
303
+ val on = r == selected
304
+ Column(
305
+ horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally,
306
+ modifier = Modifier
307
+ .weight(1f)
308
+ .heightIn(min = 44.dp) // 44dp min touch even though visual is smaller
309
+ .clickableNoRipple {
310
+ onSelect(r)
311
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove)
312
+ },
313
+ ) {
314
+ Text(
315
+ r,
316
+ style = RobinhoodText.RangeChip,
317
+ color = if (on) active else RobinhoodColors.TextSecondary,
318
+ modifier = Modifier.padding(vertical = 6.dp),
319
+ )
320
+ Box(
321
+ Modifier
322
+ .fillMaxWidth()
323
+ .height(2.dp)
324
+ .background(if (on) active else Color.Transparent)
325
+ )
326
+ }
327
+ }
328
+ }
329
+ }
330
+
331
+ import androidx.compose.foundation.clickable
332
+ import androidx.compose.foundation.interaction.MutableInteractionSource
333
+ import androidx.compose.ui.composed
334
+ fun Modifier.clickableNoRipple(onClick: () -> Unit): Modifier = composed {
335
+ clickable(remember { MutableInteractionSource() }, indication = null, onClick = onClick)
336
+ }
337
+ ```
338
+
339
+ ### Position Row
340
+
341
+ 56.dp tall. 32.dp rounded-square logo, company name above tracked ticker + share count, market value + day-change (tabular) right-aligned, 0.5.dp bottom divider.
342
+
343
+ ```kotlin
344
+ import androidx.compose.foundation.shape.RoundedCornerShape
345
+ import androidx.compose.ui.draw.clip
346
+ import androidx.compose.ui.layout.ContentScale
347
+ import androidx.compose.ui.Alignment
348
+ import coil.compose.AsyncImage
349
+
350
+ @Composable
351
+ fun PositionRow(
352
+ ticker: String,
353
+ company: String,
354
+ shares: Double,
355
+ marketValue: Double,
356
+ dayChange: Double,
357
+ dayChangePct: Double,
358
+ logoUrl: String?,
359
+ modifier: Modifier = Modifier,
360
+ ) {
361
+ val up = dayChange >= 0
362
+ val changeColor = if (up) RobinhoodColors.Green else RobinhoodColors.Red
363
+ val sign = if (up) "+" else "−"
364
+
365
+ Row(
366
+ modifier = modifier
367
+ .fillMaxWidth()
368
+ .height(56.dp)
369
+ .padding(horizontal = 16.dp),
370
+ verticalAlignment = Alignment.CenterVertically,
371
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
372
+ ) {
373
+ if (logoUrl != null) {
374
+ AsyncImage(
375
+ model = logoUrl,
376
+ contentDescription = null,
377
+ contentScale = ContentScale.Crop,
378
+ modifier = Modifier.size(32.dp).clip(RoundedCornerShape(8.dp)),
379
+ )
380
+ } else {
381
+ Box(
382
+ Modifier.size(32.dp).clip(RoundedCornerShape(8.dp)).background(RobinhoodColors.SurfaceGray),
383
+ contentAlignment = Alignment.Center,
384
+ ) { Text(ticker.take(1), style = RobinhoodText.PositionTitle, color = RobinhoodColors.TextPrimary) }
385
+ }
386
+
387
+ Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(2.dp)) {
388
+ Text(company, style = RobinhoodText.PositionTitle, color = RobinhoodColors.TextPrimary, maxLines = 1)
389
+ Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
390
+ Text(ticker, style = RobinhoodText.Ticker, color = RobinhoodColors.TextSecondary)
391
+ Text("· ${shares.formatShares()} shares", style = RobinhoodText.BodySmall, color = RobinhoodColors.TextSecondary)
392
+ }
393
+ }
394
+
395
+ Column(horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.spacedBy(2.dp)) {
396
+ Text(usd.format(marketValue), style = RobinhoodText.PositionValue, color = RobinhoodColors.TextPrimary)
397
+ Text(
398
+ "$sign${usd.format(kotlin.math.abs(dayChange))} ($sign${"%.2f".format(dayChangePct * 100)}%)",
399
+ style = RobinhoodText.PositionChange,
400
+ color = changeColor,
401
+ )
402
+ }
403
+ }
404
+ Spacer(Modifier.fillMaxWidth().height(0.5.dp).background(RobinhoodColors.DividerLight))
405
+ }
406
+
407
+ private fun Double.formatShares(): String =
408
+ if (this % 1.0 == 0.0) toInt().toString() else "%.4f".format(this).trimEnd('0').trimEnd('.')
409
+ ```
410
+
411
+ ### Trade Button (sticky footer) & Buy/Sell Pair
412
+
413
+ The universal Trade CTA is **black** — green/orange are reserved for Buy/Sell inside the trade flow.
414
+
415
+ ```kotlin
416
+ @Composable
417
+ fun TradeButton(label: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
418
+ val haptics = LocalHapticFeedback.current
419
+ Box(
420
+ modifier = modifier
421
+ .fillMaxWidth()
422
+ .padding(horizontal = 16.dp)
423
+ .height(48.dp)
424
+ .clip(RoundedCornerShape(8.dp))
425
+ .background(RobinhoodColors.TextPrimary) // black, not green
426
+ .clickableNoRipple {
427
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ~impact medium
428
+ onClick()
429
+ },
430
+ contentAlignment = Alignment.Center,
431
+ ) { Text(label, style = RobinhoodText.ButtonPrimary, color = Color.White) }
432
+ }
433
+
434
+ @Composable
435
+ fun BuySellButtons(onBuy: () -> Unit, onSell: () -> Unit, modifier: Modifier = Modifier) {
436
+ Row(modifier.fillMaxWidth().padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
437
+ Box(
438
+ Modifier.weight(1f).height(48.dp).clip(RoundedCornerShape(8.dp))
439
+ .background(RobinhoodColors.Red).clickableNoRipple(onSell),
440
+ contentAlignment = Alignment.Center,
441
+ ) { Text("Sell", style = RobinhoodText.ButtonPrimary, color = Color.White) }
442
+ Box(
443
+ Modifier.weight(1f).height(48.dp).clip(RoundedCornerShape(8.dp))
444
+ .background(RobinhoodColors.Green).clickableNoRipple(onBuy),
445
+ contentAlignment = Alignment.Center,
446
+ ) { Text("Buy", style = RobinhoodText.ButtonPrimary, color = Color.White) }
447
+ }
448
+ }
449
+ ```
450
+
451
+ ## 4. The Portfolio Chart Scrubber — wiring the live hero update
452
+
453
+ §3 draws the chart; this is the data flow that makes the scrubber Robinhood's signature. The screen owns the scrub index; while dragging, the hero shows the scrubbed value and on release snaps back to current. The numeric morph runs in <100ms via `AnimatedContent`.
454
+
455
+ ```kotlin
456
+ @Composable
457
+ fun InvestingScreen(
458
+ series: List<Pair<Long, Float>>, // (epochMillis, portfolioValue)
459
+ currentValue: Double,
460
+ dayChange: Double,
461
+ dayChangePct: Double,
462
+ ) {
463
+ var scrubIndex by remember { mutableStateOf<Int?>(null) }
464
+ val isUp = dayChange >= 0
465
+ val shownValue = scrubIndex?.let { series[it].second.toDouble() } ?: currentValue
466
+
467
+ Column {
468
+ PortfolioHero(
469
+ portfolioValue = shownValue, // updates live during scrub
470
+ dayChange = dayChange,
471
+ dayChangePct = dayChangePct,
472
+ )
473
+ PortfolioChart(
474
+ points = series.map { it.second },
475
+ isUp = isUp,
476
+ onScrub = { scrubIndex = it }, // null on release → snaps back
477
+ )
478
+ ChartRangeChips(selected = "1D", isUp = isUp, onSelect = { /* reload series */ })
479
+ }
480
+ }
481
+ ```
482
+
483
+ Reduce-motion: skip the `AnimatedContent` morph during scrubbing — swap the value instantly (drag is already 60fps with no smoothing).
484
+
485
+ ## 5. Bottom Navigation (Tab Bar)
486
+
487
+ Five labeled destinations in a Material 3 `NavigationBar`: Investing, Search, Crypto, Cash, Account. Active tint is **black** (not green — green is the direction signal). Solid surface, 0.5.dp top divider, no blur. Below it, a single sticky black Trade footer on the stock-detail screen.
488
+
489
+ ```kotlin
490
+ import androidx.compose.material.icons.Icons
491
+ import androidx.compose.material.icons.filled.*
492
+ import androidx.compose.material3.*
493
+
494
+ @Composable
495
+ fun RobinhoodBottomBar(selected: Int, onSelect: (Int) -> Unit) {
496
+ val haptics = LocalHapticFeedback.current
497
+ NavigationBar(
498
+ containerColor = RobinhoodColors.CanvasLight,
499
+ tonalElevation = 0.dp,
500
+ ) {
501
+ val tabs = listOf(
502
+ "Investing" to Icons.Filled.ShowChart,
503
+ "Search" to Icons.Filled.Search,
504
+ "Crypto" to Icons.Filled.CurrencyBitcoin,
505
+ "Cash" to Icons.Filled.AccountBalanceWallet,
506
+ "Account" to Icons.Filled.AccountCircle,
507
+ )
508
+ tabs.forEachIndexed { i, (label, icon) ->
509
+ NavigationBarItem(
510
+ selected = selected == i,
511
+ onClick = {
512
+ onSelect(i)
513
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove) // selection
514
+ },
515
+ icon = { Icon(icon, label, modifier = Modifier.size(24.dp)) },
516
+ label = { Text(label, style = RobinhoodText.TabLabel) },
517
+ colors = NavigationBarItemDefaults.colors(
518
+ selectedIconColor = RobinhoodColors.TextPrimary, // black, not green
519
+ selectedTextColor = RobinhoodColors.TextPrimary,
520
+ unselectedIconColor = RobinhoodColors.TextTertiary,
521
+ unselectedTextColor = RobinhoodColors.TextTertiary,
522
+ indicatorColor = Color.Transparent,
523
+ ),
524
+ )
525
+ }
526
+ }
527
+ }
528
+ ```
529
+
530
+ ## 6. Motion
531
+
532
+ | Moment | Compose recipe |
533
+ |--------|----------------|
534
+ | Chart scrubber drag | `pointerInput` + `detectDragGestures`, snap to nearest index, **no smoothing** (instant) |
535
+ | Portfolio value update | `AnimatedContent` cross-fade `tween(90)` — <100ms numeric morph |
536
+ | Buy/Sell confirm | `animateFloatAsState` 1 → 0.97 → 1 `spring(dampingRatio = 0.7f)` + `HapticFeedbackType.LongPress` (impact medium) |
537
+ | Order placed | green particle burst (`Canvas` + `Animatable` over ~800ms) + `HapticFeedbackType.Confirm` (success) |
538
+ | Tab switch | instant icon/label color change + `HapticFeedbackType.TextHandleMove` (selection) |
539
+ | Range chip switch | `animateColorAsState` text + underline cross-fade `spring(stiffness = 700f)` |
540
+ | Position row tap | `animateColorAsState` bg white → `SurfaceGray` over 150ms before navigating |
541
+
542
+ ```kotlin
543
+ // Buy/Sell press scale
544
+ @Composable
545
+ fun rememberPressScale(interaction: MutableInteractionSource): Float {
546
+ val pressed by interaction.collectIsPressedAsState()
547
+ val scale by animateFloatAsState(
548
+ if (pressed) 0.97f else 1f,
549
+ spring(dampingRatio = 0.7f, stiffness = 500f),
550
+ label = "pressScale",
551
+ )
552
+ return scale
553
+ }
554
+ ```
555
+
556
+ Haptics: prefer `LocalHapticFeedback`. The scrub tick and tab switch use `HapticFeedbackType.TextHandleMove` (selection-like); Buy/Sell confirm uses `LongPress` (impact medium); order success uses `HapticFeedbackType.Confirm`. For finer control, `Vibrator` `VibrationEffect.createOneShot(10, ...)` approximates iOS's medium impact.
557
+
558
+ ## 7. Icons
559
+
560
+ Robinhood uses custom glyphs; the closest first-party set is `androidx.compose.material:material-icons-extended`. The portfolio chart is hand-drawn (§3, not an icon). Custom marks (success confetti, order states) ship as vector drawables via `ImageVector.vectorResource(...)`.
561
+
562
+ | Purpose | SF Symbol (iOS) | Material Icon (Compose) |
563
+ |---------|-----------------|--------------------------|
564
+ | Investing (tab) | `chart.line.uptrend.xyaxis` | `Icons.Filled.ShowChart` |
565
+ | Search (tab) | `magnifyingglass` | `Icons.Filled.Search` |
566
+ | Crypto (tab) | `bitcoinsign.circle` | `Icons.Filled.CurrencyBitcoin` |
567
+ | Cash (tab) | `wallet.pass` | `Icons.Filled.AccountBalanceWallet` |
568
+ | Account (tab) | `person.crop.circle` | `Icons.Filled.AccountCircle` |
569
+ | Search (in field) | `magnifyingglass` | `Icons.Filled.Search` |
570
+ | Set alert | `bell` / `bell.fill` | `Icons.Filled.NotificationsNone` / `Icons.Filled.Notifications` |
571
+ | Add to list | `plus.circle` | `Icons.Filled.AddCircleOutline` |
572
+ | Back | `chevron.left` | `Icons.AutoMirrored.Filled.ArrowBack` |
573
+ | Share | `square.and.arrow.up` | `Icons.Filled.IosShare` |
574
+ | Order placed (success) | `checkmark.circle.fill` | `Icons.Filled.CheckCircle` |
575
+ | Order failed | `xmark.circle.fill` | `Icons.Filled.Cancel` |
576
+
577
+ ## 8. Minimum SDK & Accessibility Notes
578
+
579
+ - **minSdk 24**. `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`. The chart is a hand-drawn `Canvas` (no extra dependency) so it works at minSdk with no Swift-Charts equivalent needed.
580
+ - **Edge-to-edge**: call `enableEdgeToEdge()`. The light canvas wants dark-content system bars (white wants light-content on dark mode). The chart goes edge-to-edge; apply `Scaffold` insets only to the hero, lists, and the sticky Trade footer (clears gesture nav).
581
+ - **Tabular numerals are critical**: every `Text` rendering a price, percent, or share count must use `fontFeatureSettings = "tnum"` (baked into the `RobinhoodText` styles). On the fallback font this guarantees columns align as the user scrolls a watchlist — the brand-defining rule.
582
+ - **Font scaling**: `sp` honors user scale on body, secondary text, list rows. The portfolio hero (40sp) scales but **clamp at 56sp** to preserve layout; chart axis labels (11sp), range chips, and tab labels are fixed (layout-sensitive) — wrap in a fixed-`fontScale` `LocalDensity`. Position values honor scaling but clamp at 22sp.
583
+ - **TalkBack**: the hero should announce "Buying power $24,847.93, up $847.93, up 3.52 percent today" via one merged `semantics`. Position rows: "Apple Inc., A A P L, 4 shares, market value $1,247.92, up $24.13, up 1.97 percent today". The chart needs a `contentDescription` summarizing the trend plus an accessible "scrub to time" affordance (the drag gesture alone is not TalkBack-reachable).
584
+ - **Color-blind**: green/orange is the primary direction signal — always pair with the `+`/`−` sign prefix (already in the components) so it is never color-only. When `isHighTextContrastEnabled`/differentiate-without-color is set, prefix an up/down arrow on the change text.
585
+ - **Touch targets**: range chips are visually small but must keep a 44.dp min hit (`heightIn(min = 44.dp)`, already applied); Trade button is 48.dp; tab items 56.dp.
586
+ - **Contrast**: `#000000` on `#FFFFFF` is maximum; `#5C6166` on white passes AA at 14sp+; `#9B9EA3` (inactive tab labels) passes AA only at 18sp+ — keep the 10sp tab label at `#000000` once selected. Dark mode: green `#00C805` and orange `#FF5000` stay identical (they read electric on `#000000`).
587
+ - **Dynamic color**: do **not** enable Material You `dynamicColorScheme()` — the stark white/true-black canvas and the direction-bound green/orange are the brand. A wallpaper-tinted primary would break the "color = direction" contract and the clean tech-product aesthetic.