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,756 @@
1
+ # Bumble (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports Bumble's visual language to **Android with Jetpack Compose (Material 3)**: a color token object, a `Typography` set, paste-ready `@Composable`s, the `Hexagon` shape, the glowing heart action button, the It's-a-Match celebration, and the 24-hour countdown chip.
4
+
5
+ > Why a Compose guide for an iOS-referenced app? The DESIGN.md tokens are platform-neutral. This file keeps the *visual* identity (Bumble's stadium-loud yellow, pure-black-on-yellow contrast, the hexagon spatial signature, the heavy Brando ladder) while making everything idiomatic Android — a custom `Shape` for the hex, `NavigationBar` instead of a UITabBar, `Brush` glow approximated with elevation + a radial scrim, `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 profile photos. No color extraction, so no `androidx.palette`.
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/BumbleColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+
15
+ object BumbleColors {
16
+ // Brand
17
+ val Yellow = Color(0xFFFFC629) // the brand — CTAs, tab indicator, match, heart
18
+ val HoneyDeep = Color(0xFFF5B616) // pressed state on yellow
19
+ val YellowLight = Color(0xFFFFE9A1) // soft chip fills, premium gradients
20
+
21
+ // Mode colors (Date / BFF / Bizz)
22
+ val BFFTeal = Color(0xFF11AAA8)
23
+ val BizzOrange = Color(0xFFFF8000)
24
+
25
+ // Canvas & Surfaces
26
+ val Canvas = Color(0xFFFFFFFF) // Date mode
27
+ val BFFCream = Color(0xFFFFFCF2) // BFF mode tint
28
+ val Surface1 = Color(0xFFF5F5F5) // input fills, settings rows
29
+ val Surface2 = Color(0xFFEDEDED) // pressed states, chip fills
30
+ val Divider = Color(0xFFE5E5E5) // 0.5dp hairlines
31
+
32
+ // Text
33
+ val Black = Color(0xFF1F1F1F) // primary on white (warm, NOT pure)
34
+ val Slate = Color(0xFF5A5A5A) // secondary
35
+ val Mist = Color(0xFF9C9C9C) // tertiary, placeholders
36
+ val OnYellow = Color(0xFF000000) // pure black — required on yellow for WCAG AA
37
+
38
+ // Semantic
39
+ val MatchPink = Color(0xFFE94B7B) // ONLY the It's-a-Match heart
40
+ val Verified = Color(0xFF0066FF) // verified checkmark
41
+ val Warning = Color(0xFFFF9500) // incomplete-profile warning
42
+ val Error = Color(0xFFD72638) // validation errors, expired countdown
43
+ val Success = Color(0xFF00A86B) // confirmation toasts
44
+
45
+ // Dark mode (warm OLED — yellow unchanged)
46
+ val DarkCanvas = Color(0xFF0F0F0F)
47
+ val DarkSurface1 = Color(0xFF1A1A1A)
48
+ val DarkSurface2 = Color(0xFF2A2A2A)
49
+ val DarkDivider = Color(0xFF2F2F2F)
50
+ val DarkText = Color(0xFFF2F2F2)
51
+ val DarkTextSec = Color(0xFF9C9C9C)
52
+ val HoneyDeepDk = Color(0xFFFFD45C) // brightened for OLED pressed states
53
+ }
54
+ ```
55
+
56
+ Wire it into a Material 3 `lightColorScheme` (Date mode) — Bumble's primary surface is white. Provide a parallel dark scheme; the yellow stays identical because it reads loud on OLED.
57
+
58
+ ```kotlin
59
+ // ui/theme/Theme.kt
60
+ import androidx.compose.foundation.isSystemInDarkTheme
61
+ import androidx.compose.material3.darkColorScheme
62
+ import androidx.compose.material3.lightColorScheme
63
+ import androidx.compose.material3.MaterialTheme
64
+
65
+ private val BumbleLight = lightColorScheme(
66
+ primary = BumbleColors.Yellow,
67
+ onPrimary = BumbleColors.OnYellow, // pure black on yellow — non-negotiable
68
+ background = BumbleColors.Canvas,
69
+ onBackground = BumbleColors.Black,
70
+ surface = BumbleColors.Canvas,
71
+ onSurface = BumbleColors.Black,
72
+ surfaceVariant = BumbleColors.Surface1,
73
+ outline = BumbleColors.Divider,
74
+ error = BumbleColors.Error,
75
+ )
76
+
77
+ private val BumbleDark = darkColorScheme(
78
+ primary = BumbleColors.Yellow, // unchanged on dark
79
+ onPrimary = BumbleColors.OnYellow,
80
+ background = BumbleColors.DarkCanvas,
81
+ onBackground = BumbleColors.DarkText,
82
+ surface = BumbleColors.DarkSurface1,
83
+ onSurface = BumbleColors.DarkText,
84
+ surfaceVariant = BumbleColors.DarkSurface2,
85
+ outline = BumbleColors.DarkDivider,
86
+ error = BumbleColors.Error,
87
+ )
88
+
89
+ @Composable
90
+ fun BumbleTheme(content: @Composable () -> Unit) =
91
+ MaterialTheme(
92
+ colorScheme = if (isSystemInDarkTheme()) BumbleDark else BumbleLight,
93
+ typography = BumbleTypography,
94
+ content = content,
95
+ )
96
+ ```
97
+
98
+ ## 2. Typography
99
+
100
+ Brando is the proprietary Bumble face — slab-influenced, humanist, heavy. Drop the TTFs in `res/font/` (lowercase, snake_case). Bumble has **no Light or Thin** — only 400/500/700/900. Fall back to Roboto (the closest free Android substitute); for a tighter brand match consider bundling Bricolage Grotesque / Manrope Heavy.
101
+
102
+ ```kotlin
103
+ // ui/theme/BumbleType.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 Brando = FontFamily(
112
+ Font(R.font.brando_regular, FontWeight.Normal), // 400
113
+ Font(R.font.brando_medium, FontWeight.Medium), // 500
114
+ Font(R.font.brando_bold, FontWeight.Bold), // 700
115
+ Font(R.font.brando_black, FontWeight.Black), // 900
116
+ )
117
+
118
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1, same weights/tracking)
119
+ object BumbleText {
120
+ val MatchHero = TextStyle(Brando, fontWeight = FontWeight.Black, fontSize = 44.sp, lineHeight = 46.sp, letterSpacing = (-0.8).sp)
121
+ val Display = TextStyle(Brando, fontWeight = FontWeight.Black, fontSize = 32.sp, lineHeight = 35.sp, letterSpacing = (-0.6).sp)
122
+ val ScreenTitle = TextStyle(Brando, fontWeight = FontWeight.Black, fontSize = 24.sp, lineHeight = 28.sp, letterSpacing = (-0.4).sp)
123
+ val CardName = TextStyle(Brando, fontWeight = FontWeight.Bold, fontSize = 28.sp, lineHeight = 31.sp, letterSpacing = (-0.4).sp)
124
+ val Section = TextStyle(Brando, fontWeight = FontWeight.Bold, fontSize = 18.sp, lineHeight = 22.sp, letterSpacing = (-0.1).sp)
125
+ val Body = TextStyle(Brando, fontWeight = FontWeight.Medium, fontSize = 16.sp, lineHeight = 22.sp)
126
+ val BodyBold = TextStyle(Brando, fontWeight = FontWeight.Bold, fontSize = 16.sp, lineHeight = 22.sp)
127
+ val BodySmall = TextStyle(Brando, fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 20.sp)
128
+ val Button = TextStyle(Brando, fontWeight = FontWeight.Bold, fontSize = 16.sp, lineHeight = 16.sp)
129
+ val ButtonLarge = TextStyle(Brando, fontWeight = FontWeight.Bold, fontSize = 18.sp, lineHeight = 18.sp)
130
+ val Tab = TextStyle(Brando, fontWeight = FontWeight.Bold, fontSize = 10.sp, lineHeight = 10.sp, letterSpacing = 0.2.sp)
131
+ val Chip = TextStyle(Brando, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 13.sp)
132
+ val Meta = TextStyle(Brando, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 17.sp)
133
+ val Counter = TextStyle(Brando, fontWeight = FontWeight.Bold, fontSize = 11.sp, lineHeight = 11.sp, letterSpacing = 0.2.sp)
134
+ val Compliment = TextStyle(Brando, fontWeight = FontWeight.Black, fontSize = 22.sp, lineHeight = 26.sp, letterSpacing = (-0.3).sp)
135
+ }
136
+
137
+ // Map onto Material 3 slots so stock components inherit the brand
138
+ val BumbleTypography = Typography(
139
+ displayLarge = BumbleText.Display,
140
+ headlineLarge = BumbleText.ScreenTitle,
141
+ titleLarge = BumbleText.CardName,
142
+ titleMedium = BumbleText.Section,
143
+ bodyMedium = BumbleText.Body,
144
+ labelSmall = BumbleText.Tab,
145
+ )
146
+ ```
147
+
148
+ The 24-hour countdown is the only place numerals must hold column width — pin tabular figures on `Meta` (countdown) and `Counter` (badges) with `TextStyle(fontFeatureSettings = "tnum")`.
149
+
150
+ ## 3. Signature Components
151
+
152
+ ### Hexagon Shape (the brand spatial signature)
153
+
154
+ Bumble's hex is point-up. This is the SwiftUI `Hexagon: Shape` ported to a Compose `Shape` — reuse it for match avatars, mode-toggle buttons, and the brand mark.
155
+
156
+ ```kotlin
157
+ import androidx.compose.ui.geometry.Offset
158
+ import androidx.compose.ui.graphics.Outline
159
+ import androidx.compose.ui.graphics.Path
160
+ import androidx.compose.ui.graphics.Shape
161
+ import androidx.compose.ui.unit.Density
162
+ import androidx.compose.ui.unit.LayoutDirection
163
+ import kotlin.math.cos
164
+ import kotlin.math.min
165
+ import kotlin.math.sin
166
+
167
+ val HexagonShape = object : Shape {
168
+ override fun createOutline(
169
+ size: androidx.compose.ui.geometry.Size,
170
+ layoutDirection: LayoutDirection,
171
+ density: Density,
172
+ ): Outline {
173
+ val r = min(size.width, size.height) / 2f
174
+ val cx = size.width / 2f
175
+ val cy = size.height / 2f
176
+ val path = Path()
177
+ for (i in 0 until 6) {
178
+ val angle = (Math.PI / 3 * i - Math.PI / 2).toFloat() // point-up
179
+ val x = cx + r * cos(angle)
180
+ val y = cy + r * sin(angle)
181
+ if (i == 0) path.moveTo(x, y) else path.lineTo(x, y)
182
+ }
183
+ path.close()
184
+ return Outline.Generic(path)
185
+ }
186
+ }
187
+ ```
188
+
189
+ ### Yellow Primary CTA
190
+
191
+ ```kotlin
192
+ import androidx.compose.animation.core.animateFloatAsState
193
+ import androidx.compose.animation.core.spring
194
+ import androidx.compose.foundation.background
195
+ import androidx.compose.foundation.interaction.MutableInteractionSource
196
+ import androidx.compose.foundation.interaction.collectIsPressedAsState
197
+ import androidx.compose.foundation.layout.*
198
+ import androidx.compose.foundation.shape.CircleShape
199
+ import androidx.compose.material3.Text
200
+ import androidx.compose.runtime.*
201
+ import androidx.compose.ui.Alignment
202
+ import androidx.compose.ui.Modifier
203
+ import androidx.compose.ui.draw.clip
204
+ import androidx.compose.ui.draw.scale
205
+ import androidx.compose.ui.draw.shadow
206
+ import androidx.compose.ui.graphics.Color
207
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
208
+ import androidx.compose.ui.platform.LocalHapticFeedback
209
+ import androidx.compose.foundation.clickable
210
+ import androidx.compose.ui.unit.dp
211
+
212
+ @Composable
213
+ fun BumblePrimaryButton(
214
+ label: String,
215
+ onClick: () -> Unit,
216
+ modifier: Modifier = Modifier,
217
+ hasGlow: Boolean = false,
218
+ ) {
219
+ val interaction = remember { MutableInteractionSource() }
220
+ val pressed by interaction.collectIsPressedAsState()
221
+ val scale by animateFloatAsState(if (pressed) 0.97f else 1f, label = "ctaScale")
222
+ val haptics = LocalHapticFeedback.current
223
+
224
+ Box(
225
+ modifier = modifier
226
+ .fillMaxWidth()
227
+ .height(56.dp)
228
+ .scale(scale)
229
+ // Yellow glow halo — Android has no colored blur shadow, so a tinted
230
+ // ambient/spot shadow approximates the brand glow on hero CTAs.
231
+ .then(
232
+ if (hasGlow)
233
+ Modifier.shadow(24.dp, CircleShape, ambientColor = BumbleColors.Yellow,
234
+ spotColor = BumbleColors.Yellow)
235
+ else Modifier
236
+ )
237
+ .clip(CircleShape) // 28dp capsule == full pill at 56dp height
238
+ .background(if (pressed) BumbleColors.HoneyDeep else BumbleColors.Yellow)
239
+ .clickable(interaction, indication = null) {
240
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ≈ .impact(.medium)
241
+ onClick()
242
+ },
243
+ contentAlignment = Alignment.Center,
244
+ ) {
245
+ Text(label, style = BumbleText.Button, color = BumbleColors.OnYellow) // pure black
246
+ }
247
+ }
248
+ ```
249
+
250
+ ### Swipe Action Row (under the swipe card)
251
+
252
+ Five circular buttons; the yellow heart is the hero with a glow halo. Press scales to 0.9; the haptic varies per button.
253
+
254
+ ```kotlin
255
+ import androidx.compose.foundation.border
256
+ import androidx.compose.material.icons.Icons
257
+ import androidx.compose.material.icons.filled.Close
258
+ import androidx.compose.material.icons.filled.Favorite
259
+ import androidx.compose.material.icons.filled.Star
260
+ import androidx.compose.material.icons.automirrored.filled.Undo
261
+ import androidx.compose.material3.Icon
262
+ import androidx.compose.ui.graphics.vector.ImageVector
263
+
264
+ @Composable
265
+ fun SwipeActionRow(
266
+ onRewind: () -> Unit,
267
+ onPass: () -> Unit,
268
+ onLike: () -> Unit,
269
+ onSuper: () -> Unit,
270
+ onCompliment: () -> Unit,
271
+ modifier: Modifier = Modifier,
272
+ ) {
273
+ Row(
274
+ modifier.fillMaxWidth(),
275
+ horizontalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterHorizontally),
276
+ verticalAlignment = Alignment.CenterVertically,
277
+ ) {
278
+ ActionCircle(48.dp, BumbleColors.Surface1, null, HapticFeedbackType.TextHandleMove, onRewind) {
279
+ Icon(Icons.AutoMirrored.Filled.Undo, "Rewind", tint = BumbleColors.Mist, modifier = Modifier.size(20.dp))
280
+ }
281
+ ActionCircle(56.dp, BumbleColors.Canvas, BumbleColors.Black, HapticFeedbackType.TextHandleMove, onPass) {
282
+ Icon(Icons.Filled.Close, "Pass", tint = BumbleColors.Black, modifier = Modifier.size(22.dp))
283
+ }
284
+ // Heart Yes — 64dp hero with yellow glow halo
285
+ HeartActionButton(onLike)
286
+ ActionCircle(56.dp, BumbleColors.Yellow, null, HapticFeedbackType.LongPress, onSuper) {
287
+ Icon(Icons.Filled.Star, "SuperSwipe", tint = BumbleColors.OnYellow, modifier = Modifier.size(22.dp))
288
+ }
289
+ ActionCircle(56.dp, BumbleColors.Canvas, BumbleColors.Yellow, HapticFeedbackType.TextHandleMove, onCompliment) {
290
+ // Bee glyph is proprietary — ship as a vector drawable; placeholder star here
291
+ Icon(Icons.Filled.Star, "Compliment", tint = BumbleColors.Yellow, modifier = Modifier.size(22.dp))
292
+ }
293
+ }
294
+ }
295
+
296
+ @Composable
297
+ private fun ActionCircle(
298
+ diameter: androidx.compose.ui.unit.Dp,
299
+ fill: Color,
300
+ stroke: Color?,
301
+ haptic: HapticFeedbackType,
302
+ onClick: () -> Unit,
303
+ content: @Composable () -> Unit,
304
+ ) {
305
+ val interaction = remember { MutableInteractionSource() }
306
+ val pressed by interaction.collectIsPressedAsState()
307
+ val scale by animateFloatAsState(if (pressed) 0.9f else 1f, label = "actionScale")
308
+ val haptics = LocalHapticFeedback.current
309
+ Box(
310
+ Modifier
311
+ .size(diameter)
312
+ .scale(scale)
313
+ .clip(CircleShape)
314
+ .background(fill)
315
+ .then(if (stroke != null) Modifier.border(1.5.dp, stroke, CircleShape) else Modifier)
316
+ .clickable(interaction, indication = null) { haptics.performHapticFeedback(haptic); onClick() },
317
+ contentAlignment = Alignment.Center,
318
+ ) { content() }
319
+ }
320
+
321
+ @Composable
322
+ private fun HeartActionButton(onLike: () -> Unit) {
323
+ val interaction = remember { MutableInteractionSource() }
324
+ val pressed by interaction.collectIsPressedAsState()
325
+ val scale by animateFloatAsState(
326
+ targetValue = if (pressed) 1.2f else 1f,
327
+ animationSpec = spring(dampingRatio = 0.6f, stiffness = 600f),
328
+ label = "heartScale",
329
+ )
330
+ val haptics = LocalHapticFeedback.current
331
+ Box(
332
+ Modifier
333
+ .size(64.dp)
334
+ .scale(scale)
335
+ .shadow(16.dp, CircleShape, ambientColor = BumbleColors.Yellow, spotColor = BumbleColors.Yellow)
336
+ .clip(CircleShape)
337
+ .background(BumbleColors.Yellow)
338
+ .clickable(interaction, indication = null) {
339
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ≈ .impact(.medium)
340
+ onLike()
341
+ },
342
+ contentAlignment = Alignment.Center,
343
+ ) { Icon(Icons.Filled.Favorite, "Like", tint = BumbleColors.OnYellow, modifier = Modifier.size(28.dp)) }
344
+ }
345
+ ```
346
+
347
+ ### Swipe Card (the hero component)
348
+
349
+ 3:4 photo, 12dp radius (firmer edge than Hinge), 4-segment Stories-style progress bar at the top, bottom gradient carrying name + verified check + bio.
350
+
351
+ ```kotlin
352
+ import androidx.compose.foundation.gestures.detectHorizontalDragGestures
353
+ import androidx.compose.material.icons.filled.Verified
354
+ import androidx.compose.foundation.shape.RoundedCornerShape
355
+ import androidx.compose.ui.graphics.Brush
356
+ import androidx.compose.ui.input.pointer.pointerInput
357
+ import androidx.compose.ui.layout.ContentScale
358
+ import androidx.compose.ui.text.style.TextOverflow
359
+ import coil.compose.AsyncImage
360
+
361
+ @Composable
362
+ fun SwipeCard(
363
+ photoUrls: List<String>,
364
+ name: String,
365
+ age: Int,
366
+ bio: String,
367
+ isVerified: Boolean,
368
+ onSwiped: (liked: Boolean) -> Unit,
369
+ modifier: Modifier = Modifier,
370
+ ) {
371
+ var current by remember { mutableStateOf(0) }
372
+ var dragX by remember { mutableStateOf(0f) }
373
+
374
+ Box(
375
+ modifier = modifier
376
+ .fillMaxWidth()
377
+ .aspectRatio(3f / 4f)
378
+ .shadow(16.dp, RoundedCornerShape(12.dp), spotColor = Color.Black.copy(alpha = 0.12f))
379
+ .clip(RoundedCornerShape(12.dp))
380
+ .pointerInput(Unit) {
381
+ detectHorizontalDragGestures(
382
+ onDragEnd = { if (kotlin.math.abs(dragX) > size.width * 0.3f) onSwiped(dragX > 0); dragX = 0f },
383
+ ) { _, drag -> dragX += drag }
384
+ },
385
+ ) {
386
+ AsyncImage(
387
+ model = photoUrls[current],
388
+ contentDescription = "$name, $age",
389
+ modifier = Modifier.fillMaxSize(),
390
+ contentScale = ContentScale.Crop,
391
+ )
392
+ // Bottom gradient overlay (bottom 30%, transparent → 0.7 black)
393
+ Box(
394
+ Modifier
395
+ .align(Alignment.BottomCenter)
396
+ .fillMaxWidth()
397
+ .fillMaxHeight(0.3f)
398
+ .background(Brush.verticalGradient(listOf(Color.Transparent, Color.Black.copy(alpha = 0.7f))))
399
+ )
400
+ // Photo progress bar — 4 segments, 3dp tall, 4dp gap
401
+ Row(
402
+ Modifier.fillMaxWidth().padding(12.dp),
403
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
404
+ ) {
405
+ repeat(photoUrls.size) { i ->
406
+ Box(
407
+ Modifier
408
+ .weight(1f)
409
+ .height(3.dp)
410
+ .clip(CircleShape)
411
+ .background(if (i == current) Color.White else Color.White.copy(alpha = 0.4f))
412
+ )
413
+ }
414
+ }
415
+ // Name + age + verified + bio
416
+ Column(
417
+ Modifier.align(Alignment.BottomStart).padding(horizontal = 20.dp, vertical = 20.dp),
418
+ verticalArrangement = Arrangement.spacedBy(4.dp),
419
+ ) {
420
+ Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
421
+ Text("$name, $age", style = BumbleText.CardName, color = Color.White)
422
+ if (isVerified) {
423
+ Icon(Icons.Filled.Verified, "Verified", tint = BumbleColors.Verified, modifier = Modifier.size(18.dp))
424
+ }
425
+ }
426
+ Text(bio, style = BumbleText.Body, color = Color.White, maxLines = 1, overflow = TextOverflow.Ellipsis)
427
+ }
428
+ }
429
+ }
430
+ ```
431
+
432
+ ### 24-Hour Countdown Chip (the core mechanic)
433
+
434
+ ```kotlin
435
+ import androidx.compose.animation.core.RepeatMode
436
+ import androidx.compose.animation.core.infiniteRepeatable
437
+ import androidx.compose.animation.core.rememberInfiniteTransition
438
+ import androidx.compose.animation.core.tween
439
+ import androidx.compose.ui.draw.alpha
440
+
441
+ @Composable
442
+ fun CountdownChip(remainingSeconds: Long, modifier: Modifier = Modifier) {
443
+ val expired = remainingSeconds <= 0
444
+ val label = if (expired) "Time's up — extend?"
445
+ else "Your turn: ${remainingSeconds / 3600}h ${(remainingSeconds % 3600) / 60}m"
446
+
447
+ val t = rememberInfiniteTransition(label = "countdownPulse")
448
+ val a by t.animateFloat(
449
+ initialValue = 0.95f, targetValue = 1f,
450
+ animationSpec = infiniteRepeatable(tween(1500), RepeatMode.Reverse),
451
+ label = "pulse",
452
+ )
453
+
454
+ Box(
455
+ modifier
456
+ .fillMaxWidth()
457
+ .height(32.dp)
458
+ .alpha(a)
459
+ .clip(CircleShape)
460
+ .background(if (expired) BumbleColors.Error else BumbleColors.Yellow)
461
+ .border(1.dp, if (expired) BumbleColors.Error else BumbleColors.HoneyDeep, CircleShape)
462
+ .padding(horizontal = 16.dp),
463
+ contentAlignment = Alignment.Center,
464
+ ) {
465
+ Text(
466
+ label,
467
+ style = BumbleText.Meta.copy(fontWeight = FontWeight.Bold, fontFeatureSettings = "tnum"),
468
+ color = if (expired) Color.White else BumbleColors.OnYellow, // pure black on yellow
469
+ )
470
+ }
471
+ }
472
+ ```
473
+
474
+ ### It's a Match! Celebration
475
+
476
+ ```kotlin
477
+ import androidx.compose.animation.core.Animatable
478
+ import androidx.compose.ui.draw.scale
479
+
480
+ @Composable
481
+ fun MatchCelebration(
482
+ myAvatarUrl: String,
483
+ theirAvatarUrl: String,
484
+ theirName: String,
485
+ onSendMessage: () -> Unit,
486
+ onKeepSwiping: () -> Unit,
487
+ ) {
488
+ val heartScale = remember { Animatable(0.2f) }
489
+ val haptics = LocalHapticFeedback.current
490
+
491
+ LaunchedEffect(Unit) {
492
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ≈ .notification(.success)
493
+ heartScale.animateTo(1f, spring(dampingRatio = 0.55f, stiffness = 500f)) // bounce in
494
+ }
495
+
496
+ Box(Modifier.fillMaxSize().background(BumbleColors.Yellow)) { // full-screen yellow canvas
497
+ Column(
498
+ Modifier.fillMaxSize().padding(horizontal = 24.dp),
499
+ horizontalAlignment = Alignment.CenterHorizontally,
500
+ verticalArrangement = Arrangement.Center,
501
+ ) {
502
+ Box(contentAlignment = Alignment.Center) {
503
+ Row(horizontalArrangement = Arrangement.spacedBy(32.dp)) {
504
+ HexAvatar(myAvatarUrl)
505
+ HexAvatar(theirAvatarUrl)
506
+ }
507
+ Icon(
508
+ Icons.Filled.Favorite, contentDescription = null,
509
+ tint = BumbleColors.MatchPink, // ONLY place this pink appears
510
+ modifier = Modifier.size(48.dp).scale(heartScale.value),
511
+ )
512
+ }
513
+ Spacer(Modifier.height(24.dp))
514
+ Text("It's a Match!", style = BumbleText.MatchHero, color = BumbleColors.Black)
515
+ Text("You and $theirName want to chat", style = BumbleText.Body, color = BumbleColors.Black)
516
+ Spacer(Modifier.height(12.dp))
517
+ Text("She has 24 hours to make the first move", style = BumbleText.Meta,
518
+ color = BumbleColors.Black.copy(alpha = 0.8f))
519
+ Spacer(Modifier.height(48.dp))
520
+ // Primary CTA is WHITE here (yellow canvas) with warm-black text
521
+ Box(
522
+ Modifier.fillMaxWidth().height(56.dp).clip(CircleShape).background(Color.White)
523
+ .clickable { onSendMessage() },
524
+ contentAlignment = Alignment.Center,
525
+ ) { Text("Send a Message", style = BumbleText.ButtonLarge, color = BumbleColors.Black) }
526
+ Spacer(Modifier.height(16.dp))
527
+ Text("Keep Swiping", style = BumbleText.Button, color = BumbleColors.Black,
528
+ modifier = Modifier.clickable { onKeepSwiping() })
529
+ }
530
+ }
531
+ }
532
+
533
+ @Composable
534
+ fun HexAvatar(url: String, size: androidx.compose.ui.unit.Dp = 120.dp) {
535
+ AsyncImage(
536
+ model = url,
537
+ contentDescription = null,
538
+ modifier = Modifier
539
+ .size(size)
540
+ .clip(HexagonShape)
541
+ .border(4.dp, Color.White, HexagonShape),
542
+ contentScale = ContentScale.Crop,
543
+ )
544
+ }
545
+ ```
546
+
547
+ ### Chat Input with Send Button
548
+
549
+ ```kotlin
550
+ import androidx.compose.foundation.text.BasicTextField
551
+ import androidx.compose.material.icons.filled.ArrowUpward
552
+ import androidx.compose.ui.text.input.TextFieldValue
553
+
554
+ @Composable
555
+ fun BumbleChatInput(
556
+ value: TextFieldValue,
557
+ onValueChange: (TextFieldValue) -> Unit,
558
+ onSend: () -> Unit,
559
+ modifier: Modifier = Modifier,
560
+ ) {
561
+ val canSend = value.text.isNotBlank()
562
+ val haptics = LocalHapticFeedback.current
563
+ Row(
564
+ modifier.fillMaxWidth().padding(16.dp),
565
+ verticalAlignment = Alignment.CenterVertically,
566
+ horizontalArrangement = Arrangement.spacedBy(10.dp),
567
+ ) {
568
+ Box(
569
+ Modifier.weight(1f).clip(CircleShape).background(BumbleColors.Surface1)
570
+ .padding(horizontal = 20.dp, vertical = 14.dp),
571
+ ) {
572
+ BasicTextField(
573
+ value = value, onValueChange = onValueChange,
574
+ textStyle = BumbleText.Body.copy(color = BumbleColors.Black),
575
+ decorationBox = { inner ->
576
+ if (value.text.isEmpty()) {
577
+ Text("Type your message…", style = BumbleText.Body, color = BumbleColors.Mist)
578
+ }
579
+ inner()
580
+ },
581
+ )
582
+ }
583
+ Box(
584
+ Modifier
585
+ .size(40.dp)
586
+ .clip(CircleShape)
587
+ .background(if (canSend) BumbleColors.Yellow else BumbleColors.Surface1)
588
+ .clickable(enabled = canSend) {
589
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress)
590
+ onSend()
591
+ },
592
+ contentAlignment = Alignment.Center,
593
+ ) {
594
+ Icon(Icons.Filled.ArrowUpward, "Send",
595
+ tint = if (canSend) BumbleColors.OnYellow else BumbleColors.Mist,
596
+ modifier = Modifier.size(18.dp))
597
+ }
598
+ }
599
+ }
600
+ ```
601
+
602
+ ## 4. Mode Switching (the distinctive system)
603
+
604
+ Bumble's defining structural feature is one app, three products: Date (yellow) / BFF (teal) / Bizz (orange). Switching modes recolors **all** brand chrome while the hexagon shape stays constant. Drive this with a `CompositionLocal` so every composable reads the active accent without prop-drilling.
605
+
606
+ ```kotlin
607
+ enum class BumbleMode(val accent: Color, val pressed: Color) {
608
+ Date(BumbleColors.Yellow, BumbleColors.HoneyDeep),
609
+ BFF(BumbleColors.BFFTeal, Color(0xFF0E908E)),
610
+ Bizz(BumbleColors.BizzOrange, Color(0xFFE57300)),
611
+ }
612
+
613
+ val LocalBumbleMode = androidx.compose.runtime.staticCompositionLocalOf { BumbleMode.Date }
614
+
615
+ @Composable
616
+ fun BumbleModeProvider(mode: BumbleMode, content: @Composable () -> Unit) {
617
+ androidx.compose.runtime.CompositionLocalProvider(LocalBumbleMode provides mode, content = content)
618
+ }
619
+
620
+ // A hexagonal mode-toggle button — literally hex-shaped, not rectangular
621
+ @Composable
622
+ fun ModeHexButton(mode: BumbleMode, active: Boolean, onClick: () -> Unit) {
623
+ val haptics = LocalHapticFeedback.current
624
+ Box(
625
+ Modifier
626
+ .size(64.dp)
627
+ .clip(HexagonShape)
628
+ .then(
629
+ if (active) Modifier.background(mode.accent)
630
+ else Modifier.border(2.dp, BumbleColors.Mist, HexagonShape)
631
+ )
632
+ .clickable {
633
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove) // ≈ .selection
634
+ onClick()
635
+ },
636
+ contentAlignment = Alignment.Center,
637
+ ) {
638
+ Icon(Icons.Filled.Star, mode.name, // mode glyph (hive/heart/briefcase) — vector drawable in prod
639
+ tint = if (active) BumbleColors.OnYellow else BumbleColors.Mist, modifier = Modifier.size(24.dp))
640
+ }
641
+ }
642
+ ```
643
+
644
+ Then read `LocalBumbleMode.current.accent` anywhere yellow appears (CTAs, tab indicator, match ring) so the whole app retints on switch. The hex is never replaced with a circle.
645
+
646
+ ## 5. Navigation
647
+
648
+ Bumble has 5 bottom tabs: People / Hives / Matches / Chats / Profile — the Hives icon is a literal honeycomb. Use Material 3 `NavigationBar`. The iOS tab bar is opaque (Bumble likes hard surfaces, no blur) — Android has no live blur anyway, so use a solid `Canvas` container with a 0.5dp top divider. **Active tint is warm Bumble Black** with a 4dp yellow indicator dot below the label — not the Material pill.
649
+
650
+ ```kotlin
651
+ import androidx.compose.material.icons.filled.Chat
652
+ import androidx.compose.material.icons.filled.Hexagon
653
+ import androidx.compose.material.icons.filled.People
654
+ import androidx.compose.material.icons.filled.Person
655
+ import androidx.compose.material3.NavigationBar
656
+ import androidx.compose.material3.NavigationBarItem
657
+ import androidx.compose.material3.NavigationBarItemDefaults
658
+
659
+ @Composable
660
+ fun BumbleBottomBar(selected: Int, onSelect: (Int) -> Unit) {
661
+ val accent = LocalBumbleMode.current.accent
662
+ NavigationBar(containerColor = BumbleColors.Canvas, tonalElevation = 0.dp) {
663
+ val items = listOf(
664
+ "People" to Icons.Filled.People,
665
+ "Hives" to Icons.Filled.Hexagon,
666
+ "Matches" to Icons.Filled.Favorite,
667
+ "Chats" to Icons.Filled.Chat,
668
+ "Profile" to Icons.Filled.Person,
669
+ )
670
+ items.forEachIndexed { i, (label, icon) ->
671
+ NavigationBarItem(
672
+ selected = selected == i,
673
+ onClick = { onSelect(i) },
674
+ icon = { Icon(icon, contentDescription = label, modifier = Modifier.size(24.dp)) },
675
+ label = { Text(label, style = BumbleText.Tab) },
676
+ colors = NavigationBarItemDefaults.colors(
677
+ selectedIconColor = BumbleColors.Black, // warm black, not yellow
678
+ selectedTextColor = BumbleColors.Black,
679
+ unselectedIconColor = BumbleColors.Mist,
680
+ unselectedTextColor = BumbleColors.Mist,
681
+ indicatorColor = accent.copy(alpha = 0.0f), // no Material pill — Bumble has none
682
+ ),
683
+ )
684
+ }
685
+ }
686
+ }
687
+ ```
688
+
689
+ Render the 4dp yellow (or mode-accent) indicator dot manually 4dp beneath the selected item's label if you want exact parity — `NavigationBar` has no built-in dot affordance. The top header is a slim 56dp row (no large-title) with `ScreenTitle` text leading and trailing action glyphs.
690
+
691
+ ## 6. Motion
692
+
693
+ | Moment | Compose recipe |
694
+ |--------|----------------|
695
+ | Heart tap | `animateFloatAsState` 1 → 1.2 with `spring(dampingRatio = 0.6f)`; `HapticFeedbackType.LongPress` (.impact medium) |
696
+ | SuperSwipe (star) | full-screen yellow flash 200ms via `Animatable` alpha 0→1→0; `HapticFeedbackType.LongPress` (.success) |
697
+ | Swipe commit | `animateFloatAsState` `rotationZ` → 8° + `offset` 500dp off-screen over 350ms (`spring`) |
698
+ | Yes/No confetti | `rememberInfiniteTransition` / `Animatable` driving falling yellow hexes for 800ms |
699
+ | Match celebration | photos slide in from edges; pink heart `Animatable.animateTo(1f, spring(dampingRatio = 0.55f))` |
700
+ | 24h chip pulse | `rememberInfiniteTransition` alpha 0.95 → 1.0 over 1500ms `RepeatMode.Reverse` |
701
+ | Hex loading state | `rememberInfiniteTransition` `rotationZ` 0 → 360 over 1200ms on a 6-hex honeycomb |
702
+ | Tab switch | 200ms `tween`; indicator dot `fadeIn`; `HapticFeedbackType.TextHandleMove` (.selection) |
703
+
704
+ ```kotlin
705
+ // SuperSwipe full-screen yellow flash
706
+ @Composable
707
+ fun SuperSwipeFlash(trigger: Boolean) {
708
+ val flash = remember { Animatable(0f) }
709
+ val haptics = LocalHapticFeedback.current
710
+ LaunchedEffect(trigger) {
711
+ if (trigger) {
712
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ≈ .notification(.success)
713
+ flash.animateTo(1f, tween(200))
714
+ flash.animateTo(0f, tween(200))
715
+ }
716
+ }
717
+ if (flash.value > 0f) {
718
+ Box(Modifier.fillMaxSize().alpha(flash.value).background(BumbleColors.Yellow))
719
+ }
720
+ }
721
+ ```
722
+
723
+ Honor **Reduce Motion**: when `Settings.Global.ANIMATOR_DURATION_SCALE == 0f`, skip the hex confetti and the heart scale-bounce on match — keep the haptics. For richer haptics use `LocalView.current.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)` (API 30+) or a `Vibrator` `VibrationEffect.createOneShot(10, ...)` to approximate iOS's `.soft` Compliment tap. For the match-celebration shared photo, prefer `SharedTransitionLayout` + `Modifier.sharedElement()` (Compose 1.7+).
724
+
725
+ ## 7. Icons
726
+
727
+ Bumble uses outline/filled pairs; the closest first-party set is `androidx.compose.material:material-icons-extended`. The **bee glyph** and the **hexagonal "B" logomark** are proprietary — ship them as vector drawables and load via `ImageVector.vectorResource(R.drawable.…)`.
728
+
729
+ | Purpose | SF Symbol (iOS) | Material Icon (Compose) |
730
+ |---------|-----------------|--------------------------|
731
+ | Heart action (filled) | `heart.fill` | `Icons.Filled.Favorite` |
732
+ | X Pass | `xmark` | `Icons.Filled.Close` |
733
+ | Star SuperSwipe | `star.fill` | `Icons.Filled.Star` |
734
+ | Rewind | `arrow.uturn.backward` | `Icons.AutoMirrored.Filled.Undo` |
735
+ | Bee Compliment | `ant.fill` (placeholder) | custom vector drawable (proprietary bee) |
736
+ | Match heart | `heart.fill` (Match Pink) | `Icons.Filled.Favorite` tinted `MatchPink` |
737
+ | Send (chat input) | `arrow.up` | `Icons.Filled.ArrowUpward` |
738
+ | Verified check | `checkmark.seal.fill` | `Icons.Filled.Verified` (tint `Verified`) |
739
+ | People tab | `person.2` / `.fill` | `Icons.Filled.People` |
740
+ | Hives tab | `hexagon` / `.fill` | `Icons.Filled.Hexagon` |
741
+ | Matches tab | `heart` / `.fill` | `Icons.Filled.Favorite` |
742
+ | Chats tab | `bubble.left` / `.fill` | `Icons.Filled.Chat` |
743
+ | Profile tab | `person.crop.circle` / `.fill` | `Icons.Filled.Person` |
744
+ | Filters | `slider.horizontal.3` | `Icons.Filled.Tune` |
745
+ | Settings | `gearshape` | `Icons.Filled.Settings` |
746
+ | Brand "B" logomark | (hex bee mark) | custom vector drawable |
747
+
748
+ ## 8. Minimum SDK & Accessibility Notes
749
+
750
+ - **minSdk 24** (Compose floor is 21; modern motion + `SharedTransitionLayout` comfortable at 24). `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`.
751
+ - **Edge-to-edge**: call `enableEdgeToEdge()` in the `Activity`. The light Date canvas wants dark system-bar icons (`WindowCompat` light appearance); the dark scheme wants light icons. Pin the chat input above the IME with `Modifier.imePadding()` and the tab bar above the gesture nav with `Scaffold` insets.
752
+ - **Font scaling**: `sp` honors the user's font scale automatically — keep it on match hero, display, screen titles, body, bio, section headers. Pin layout-sensitive text (10sp tab labels, 11sp counter badges, 13sp chip labels, the 24-hour countdown) by deriving size from `dp` or wrapping in `CompositionLocalProvider(LocalDensity provides Density(density, fontScale = 1f))`.
753
+ - **TalkBack**: announce the match screen as one node — `Modifier.semantics(mergeDescendants = true) { contentDescription = "It's a Match. You and $name want to chat. She has 24 hours. Send a Message button." }`. Give the swipe card an accessibility action set (`"Like"`, `"Pass"`, `"SuperSwipe"`, `"Compliment"`) so users can act without dragging. Re-announce the countdown chip when it crosses a 30-minute boundary.
754
+ - **Touch targets**: Material guidance is 48.dp minimum. The 64dp heart and 56dp CTA clear it; the 48dp Rewind and 40dp send button are at/above the floor — keep the send button's 40dp visual inside a 48dp hit area via padding.
755
+ - **Contrast**: Bumble Yellow `#FFC629` requires **pure black** (`#000000`) text — warm `#1F1F1F` on yellow *fails* WCAG AA at small sizes. Use `BumbleColors.OnYellow` on every yellow surface, no exceptions. `#9C9C9C` Mist on white is borderline at body size — keep it to ≥14sp metadata and validate with a contrast checker.
756
+ - **Dynamic color**: do **not** enable Material You `dynamicColorScheme()` — Bumble's identity is the fixed `#FFC629` yellow (and the teal/orange mode accents) regardless of wallpaper. (Material You suits Google/Material-first apps; Bumble is a strong-brand exception.) The yellow stays identical across light and dark; only canvas/surface/text tokens invert.