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,671 @@
1
+ # Snapchat (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports Snapchat'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 camera-first black canvas, the aggressive Snap Yellow, the 82dp concentric capture button, the color-coded snap-type inbox, bitmoji-as-avatar) while making everything idiomatic Android — a `HorizontalPager` for the 5-screen swipe nav instead of a paged `TabView`, `pointerInput` for the tap/long-press/double-tap capture gesture, `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 bitmoji avatars and story-preview imagery. (No `androidx.palette` — Snapchat does no color extraction; the camera feed is the content surface.)
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/SnapColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+
15
+ object SnapColors {
16
+ // Canvas & Surfaces — camera-default dark
17
+ val Canvas = Color(0xFF000000)
18
+ val Surface1 = Color(0xFF1A1A1A) // received chat bubble, discover cards, sheets
19
+ val Surface2 = Color(0xFF2C2C2C) // sent chat bubble, selected rows
20
+ val Divider = Color(0xFF333333)
21
+
22
+ // Canvas (Light — limited: settings, memories)
23
+ val LightCanvas = Color(0xFFFFFFFF)
24
+ val LightSurface1 = Color(0xFFF2F2F2)
25
+
26
+ // Text
27
+ val TextPrimary = Color(0xFFFFFFFF)
28
+ val TextPrimaryLight = Color(0xFF000000)
29
+ val TextSecondary = Color(0xFF8A8A8F)
30
+ val TextTertiary = Color(0xFF555555)
31
+
32
+ // Brand — the aggressive single accent
33
+ val Yellow = Color(0xFFFFFC00)
34
+ val YellowPressed = Color(0xFFE6E300)
35
+
36
+ // Snap type colors (color-coded inbox)
37
+ val PhotoRed = Color(0xFFFF2E3D)
38
+ val VideoPurple = Color(0xFF9B51FF)
39
+ val ChatBlue = Color(0xFF4DA7FF)
40
+ val AudioGreen = Color(0xFF4CD964)
41
+
42
+ // Semantic
43
+ val ErrorRed = Color(0xFFFF3B30)
44
+ val SuccessGreen = Color(0xFF00D873)
45
+ val LiveRed = Color(0xFFFF2E3D)
46
+
47
+ // Snap Map heat
48
+ val MapWarm = Color(0xFFFF9A1F)
49
+ }
50
+ ```
51
+
52
+ Snapchat's gravity is **dark/camera-first** — pure black, never a warm dark. Wire a Material 3 `darkColorScheme`; do not provide a light scheme as default (light appears only inside settings/memories). `primary` is Snap Yellow; `onPrimary` is black (yellow CTAs carry black text/icons). The snap-type colors are explicit tokens, never theme roles.
53
+
54
+ ```kotlin
55
+ // ui/theme/Theme.kt
56
+ import androidx.compose.material3.darkColorScheme
57
+ import androidx.compose.material3.MaterialTheme
58
+ import androidx.compose.runtime.Composable
59
+
60
+ private val SnapScheme = darkColorScheme(
61
+ primary = SnapColors.Yellow,
62
+ onPrimary = SnapColors.Canvas, // intentional: black on yellow
63
+ background = SnapColors.Canvas,
64
+ onBackground = SnapColors.TextPrimary,
65
+ surface = SnapColors.Surface1,
66
+ onSurface = SnapColors.TextPrimary,
67
+ surfaceVariant = SnapColors.Surface2,
68
+ outline = SnapColors.Divider,
69
+ error = SnapColors.ErrorRed,
70
+ )
71
+
72
+ @Composable
73
+ fun SnapTheme(content: @Composable () -> Unit) =
74
+ MaterialTheme(colorScheme = SnapScheme, typography = SnapTypography, content = content)
75
+ ```
76
+
77
+ ## 2. Typography
78
+
79
+ Avenir Next is the iOS system face; on Android it is not bundled. Drop the licensed Avenir Next TTFs in `res/font/` and build a `FontFamily`. Fall back to the system font (Roboto) — a warm humanist geometric sans is the closest free substitute. Snapchat uses **Medium (500) and Bold (700) only**, with Heavy (900) on splash/streak hero — never regular/light/thin.
80
+
81
+ ```kotlin
82
+ // ui/theme/SnapType.kt
83
+ import androidx.compose.material3.Typography
84
+ import androidx.compose.ui.text.TextStyle
85
+ import androidx.compose.ui.text.font.Font
86
+ import androidx.compose.ui.text.font.FontFamily
87
+ import androidx.compose.ui.text.font.FontWeight
88
+ import androidx.compose.ui.unit.sp
89
+
90
+ val AvenirNext = FontFamily(
91
+ Font(R.font.avenir_next_medium, FontWeight.Medium), // 500 — chat, captions
92
+ Font(R.font.avenir_next_bold, FontWeight.Bold), // 700 — names, headings, buttons
93
+ Font(R.font.avenir_next_heavy, FontWeight.Black), // 900 — splash / streak hero only
94
+ )
95
+
96
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1)
97
+ object SnapText {
98
+ val SplashTitle = TextStyle(AvenirNext, fontWeight = FontWeight.Black, fontSize = 48.sp, lineHeight = 48.sp, letterSpacing = (-0.5).sp)
99
+ val ScreenTitle = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 24.sp, lineHeight = 28.sp, letterSpacing = (-0.2).sp)
100
+ val SectionHeader = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 20.sp, lineHeight = 24.sp, letterSpacing = (-0.1).sp)
101
+ val ChatRowName = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 16.sp, lineHeight = 20.sp)
102
+ val ChatMessage = TextStyle(AvenirNext, fontWeight = FontWeight.Medium, fontSize = 16.sp, lineHeight = 21.sp)
103
+ val ChatStatus = TextStyle(AvenirNext, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 16.sp)
104
+ val StoryName = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 14.sp, lineHeight = 17.sp)
105
+ val Timestamp = TextStyle(AvenirNext, fontWeight = FontWeight.Medium, fontSize = 12.sp, lineHeight = 14.sp)
106
+ val StreakCount = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 18.sp, lineHeight = 18.sp)
107
+ val HudLabel = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 13.sp, lineHeight = 13.sp, letterSpacing = 0.3.sp)
108
+ val ButtonPrimary = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 16.sp, lineHeight = 16.sp, letterSpacing = 0.2.sp)
109
+ val LensLabel = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 13.sp, lineHeight = 13.sp, letterSpacing = 0.3.sp)
110
+ val BitmojiCallout = TextStyle(AvenirNext, fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 18.sp)
111
+ val SpotlightCap = TextStyle(AvenirNext, fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 18.sp)
112
+ val DiscoverTitle = TextStyle(AvenirNext, fontWeight = FontWeight.Bold, fontSize = 16.sp, lineHeight = 19.sp, letterSpacing = (-0.1).sp)
113
+ }
114
+
115
+ val SnapTypography = Typography(
116
+ displayMedium = SnapText.SplashTitle,
117
+ headlineSmall = SnapText.ScreenTitle,
118
+ titleMedium = SnapText.ChatRowName,
119
+ bodyMedium = SnapText.ChatMessage,
120
+ labelMedium = SnapText.Timestamp,
121
+ )
122
+ ```
123
+
124
+ ## 3. Signature Components
125
+
126
+ ### Snap Capture Button (the 82dp concentric double-circle)
127
+
128
+ The most recognizable component in the app. Outer 82dp / 6dp Snap-Yellow ring + inner 64dp white circle. Tap = photo; long-press = video (inner fills yellow, outer ring becomes a clockwise progress arc up to 60s); double-tap = camera flip. One `pointerInput` block disambiguates all three.
129
+
130
+ ```kotlin
131
+ import androidx.compose.animation.core.Animatable
132
+ import androidx.compose.animation.core.spring
133
+ import androidx.compose.foundation.Canvas
134
+ import androidx.compose.foundation.background
135
+ import androidx.compose.foundation.layout.size
136
+ import androidx.compose.foundation.shape.CircleShape
137
+ import androidx.compose.runtime.*
138
+ import androidx.compose.ui.Modifier
139
+ import androidx.compose.ui.draw.clip
140
+ import androidx.compose.ui.draw.scale
141
+ import androidx.compose.ui.geometry.Offset
142
+ import androidx.compose.ui.geometry.Size
143
+ import androidx.compose.ui.graphics.drawscope.Stroke
144
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
145
+ import androidx.compose.ui.input.pointer.pointerInput
146
+ import androidx.compose.ui.platform.LocalHapticFeedback
147
+ import androidx.compose.ui.unit.dp
148
+ import kotlinx.coroutines.delay
149
+
150
+ @Composable
151
+ fun SnapCaptureButton(
152
+ isRecording: Boolean,
153
+ recordProgress: Float, // 0f..1f over 60s
154
+ onPhoto: () -> Unit,
155
+ onVideoStart: () -> Unit,
156
+ onVideoStop: () -> Unit,
157
+ onFlip: () -> Unit,
158
+ modifier: Modifier = Modifier,
159
+ ) {
160
+ val haptics = LocalHapticFeedback.current
161
+ val innerScale = remember { Animatable(1f) }
162
+
163
+ androidx.compose.foundation.layout.Box(
164
+ modifier = modifier
165
+ .size(82.dp)
166
+ .pointerInput(Unit) {
167
+ awaitPointerEventScope {
168
+ while (true) {
169
+ val down = awaitFirstDown()
170
+ val downTime = System.currentTimeMillis()
171
+ var longFired = false
172
+ // long-press → video
173
+ val longJob = launchAndDelay(350) {
174
+ longFired = true
175
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // impact medium
176
+ onVideoStart()
177
+ }
178
+ val up = waitForUpOrCancellation()
179
+ longJob.cancel()
180
+ if (longFired) {
181
+ onVideoStop()
182
+ } else if (up != null) {
183
+ val now = System.currentTimeMillis()
184
+ if (now - lastTap < 300) { // double-tap → flip
185
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove)
186
+ onFlip()
187
+ } else { // single tap → photo
188
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // impact soft
189
+ onPhoto()
190
+ }
191
+ lastTap = now
192
+ }
193
+ }
194
+ }
195
+ },
196
+ contentAlignment = androidx.compose.ui.Alignment.Center,
197
+ ) {
198
+ // Outer yellow ring + (when recording) clockwise progress arc
199
+ Canvas(Modifier.size(82.dp)) {
200
+ val stroke = 6.dp.toPx()
201
+ drawCircle(SnapColors.Yellow, radius = (size.minDimension - stroke) / 2f, style = Stroke(stroke))
202
+ if (isRecording) {
203
+ drawArc(
204
+ color = SnapColors.Yellow,
205
+ startAngle = -90f,
206
+ sweepAngle = 360f * recordProgress,
207
+ useCenter = false,
208
+ topLeft = Offset(stroke / 2f, stroke / 2f),
209
+ size = Size(size.width - stroke, size.height - stroke),
210
+ style = Stroke(stroke),
211
+ )
212
+ }
213
+ }
214
+ // Inner circle — white, or yellow while recording
215
+ androidx.compose.foundation.layout.Box(
216
+ Modifier
217
+ .size(64.dp)
218
+ .scale(innerScale.value)
219
+ .clip(CircleShape)
220
+ .background(if (isRecording) SnapColors.Yellow else SnapColors.TextPrimary)
221
+ )
222
+ }
223
+
224
+ // photo-tap squish
225
+ LaunchedEffect(Unit) { /* drive innerScale 0.92 → 1.0 from onPhoto in real code */ }
226
+ }
227
+
228
+ // (helpers `lastTap`, `launchAndDelay` are sketches — wire to a rememberCoroutineScope in production)
229
+ ```
230
+
231
+ ### Chat Inbox Row (color-coded snap type)
232
+
233
+ 72dp tall on black, 1dp divider. 48dp circular **bitmoji**, name, then the snap-type indicator (filled square unopened / outline opened) + status, with timestamp + 🔥 streak trailing.
234
+
235
+ ```kotlin
236
+ import androidx.compose.foundation.layout.*
237
+ import androidx.compose.foundation.shape.RoundedCornerShape
238
+ import androidx.compose.material.icons.Icons
239
+ import androidx.compose.material.icons.filled.ArrowDownward
240
+ import androidx.compose.material.icons.filled.ArrowUpward
241
+ import androidx.compose.material3.Icon
242
+ import androidx.compose.material3.Text
243
+ import androidx.compose.ui.Alignment
244
+ import androidx.compose.ui.graphics.Color
245
+ import androidx.compose.ui.layout.ContentScale
246
+ import coil.compose.AsyncImage
247
+
248
+ enum class SnapType { PHOTO, VIDEO, CHAT, AUDIO, NONE }
249
+ enum class SnapDirection { INCOMING, OUTGOING }
250
+
251
+ @Composable
252
+ fun SnapChatRow(
253
+ name: String,
254
+ bitmojiUrl: String,
255
+ status: String, // "Received · 2m ago"
256
+ timestamp: String, // "2m"
257
+ snapType: SnapType,
258
+ direction: SnapDirection,
259
+ isUnread: Boolean,
260
+ streakDays: Int?,
261
+ modifier: Modifier = Modifier,
262
+ ) {
263
+ Column(modifier) {
264
+ Row(
265
+ Modifier.fillMaxWidth().height(72.dp).padding(horizontal = 16.dp),
266
+ verticalAlignment = Alignment.CenterVertically,
267
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
268
+ ) {
269
+ AsyncImage(
270
+ model = bitmojiUrl, contentDescription = null, contentScale = ContentScale.Crop,
271
+ modifier = Modifier.size(48.dp).clip(CircleShape),
272
+ )
273
+ Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(4.dp)) {
274
+ Text(name, style = SnapText.ChatRowName, color = SnapColors.TextPrimary)
275
+ Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(6.dp)) {
276
+ if (snapType != SnapType.NONE) {
277
+ SnapTypeIndicator(snapType, direction, isUnread)
278
+ }
279
+ Text(status, style = SnapText.ChatStatus, color = SnapColors.TextSecondary)
280
+ }
281
+ }
282
+ Column(horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.spacedBy(4.dp)) {
283
+ Text(timestamp, style = SnapText.Timestamp, color = SnapColors.TextSecondary)
284
+ streakDays?.let {
285
+ Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(2.dp)) {
286
+ Text("🔥")
287
+ Text("$it", style = SnapText.StreakCount, color = SnapColors.TextPrimary)
288
+ }
289
+ }
290
+ }
291
+ }
292
+ Spacer(Modifier.fillMaxWidth().height(1.dp).background(SnapColors.Divider))
293
+ }
294
+ }
295
+
296
+ @Composable
297
+ fun SnapTypeIndicator(type: SnapType, direction: SnapDirection, isUnread: Boolean) {
298
+ val color = when (type) {
299
+ SnapType.PHOTO -> SnapColors.PhotoRed
300
+ SnapType.VIDEO -> SnapColors.VideoPurple
301
+ SnapType.CHAT -> SnapColors.ChatBlue
302
+ SnapType.AUDIO -> SnapColors.AudioGreen
303
+ SnapType.NONE -> SnapColors.TextSecondary
304
+ }
305
+ Box(Modifier.size(16.dp), contentAlignment = Alignment.Center) {
306
+ Box(
307
+ Modifier
308
+ .size(16.dp)
309
+ .clip(RoundedCornerShape(2.dp))
310
+ .then(if (isUnread) Modifier.background(color) else Modifier)
311
+ .border(1.5.dp, color, RoundedCornerShape(2.dp))
312
+ )
313
+ Icon(
314
+ if (direction == SnapDirection.INCOMING) Icons.Filled.ArrowDownward else Icons.Filled.ArrowUpward,
315
+ contentDescription = null,
316
+ tint = if (isUnread) Color.White else color,
317
+ modifier = Modifier.size(8.dp),
318
+ )
319
+ }
320
+ }
321
+
322
+ import androidx.compose.foundation.border
323
+ ```
324
+
325
+ ### Story Thumbnail (pulsing unread ring)
326
+
327
+ 120dp × 200dp, 16dp corner. 3dp ring: yellow (unread, subtle 2s opacity pulse), gray (read), red (live). Bitmoji top-left, creator name bottom-left with a drop shadow for legibility on imagery.
328
+
329
+ ```kotlin
330
+ import androidx.compose.animation.core.RepeatMode
331
+ import androidx.compose.animation.core.animateFloat
332
+ import androidx.compose.animation.core.infiniteRepeatable
333
+ import androidx.compose.animation.core.rememberInfiniteTransition
334
+ import androidx.compose.animation.core.tween
335
+ import androidx.compose.ui.graphics.graphicsLayer
336
+ import androidx.compose.ui.draw.drawBehind
337
+
338
+ enum class StoryState { UNREAD, READ, LIVE }
339
+
340
+ @Composable
341
+ fun SnapStoryThumb(
342
+ creatorName: String,
343
+ bitmojiUrl: String,
344
+ previewUrl: String,
345
+ state: StoryState,
346
+ modifier: Modifier = Modifier,
347
+ ) {
348
+ val ringColor = when (state) {
349
+ StoryState.UNREAD -> SnapColors.Yellow
350
+ StoryState.READ -> SnapColors.TextTertiary
351
+ StoryState.LIVE -> SnapColors.LiveRed
352
+ }
353
+ val pulse = rememberInfiniteTransition(label = "ring")
354
+ val ringAlpha by pulse.animateFloat(
355
+ 1f, 0.7f,
356
+ infiniteRepeatable(tween(2000), RepeatMode.Reverse),
357
+ label = "ringAlpha",
358
+ )
359
+
360
+ Box(
361
+ modifier
362
+ .size(width = 120.dp, height = 200.dp)
363
+ .clip(RoundedCornerShape(16.dp))
364
+ .drawBehind { } // image drawn by AsyncImage below
365
+ ) {
366
+ AsyncImage(
367
+ model = previewUrl, contentDescription = "$creatorName story", contentScale = ContentScale.Crop,
368
+ modifier = Modifier.matchParentSize(),
369
+ )
370
+ Box(
371
+ Modifier
372
+ .matchParentSize()
373
+ .border(
374
+ width = 3.dp,
375
+ color = ringColor.copy(alpha = if (state == StoryState.UNREAD) ringAlpha else 1f),
376
+ shape = RoundedCornerShape(16.dp),
377
+ )
378
+ )
379
+ AsyncImage(
380
+ model = bitmojiUrl, contentDescription = null, contentScale = ContentScale.Crop,
381
+ modifier = Modifier.padding(8.dp).size(40.dp).clip(CircleShape).align(Alignment.TopStart),
382
+ )
383
+ Text(
384
+ creatorName,
385
+ style = SnapText.StoryName,
386
+ color = Color.White,
387
+ modifier = Modifier
388
+ .align(Alignment.BottomStart)
389
+ .padding(10.dp)
390
+ .graphicsLayer { shadowElevation = 2f }, // ~rgba(0,0,0,0.4) text shadow proxy
391
+ )
392
+ }
393
+ }
394
+ ```
395
+
396
+ ### Chat Bubble (dark gray, not iMessage-colored)
397
+
398
+ Both sent and received are dark-gray variants — never blue. 20dp corner, no tail, max 75% width.
399
+
400
+ ```kotlin
401
+ @Composable
402
+ fun SnapChatBubble(text: String, fromMe: Boolean, modifier: Modifier = Modifier) {
403
+ Row(modifier.fillMaxWidth().padding(horizontal = 16.dp)) {
404
+ if (fromMe) Spacer(Modifier.weight(1f).widthIn(min = 60.dp))
405
+ Text(
406
+ text,
407
+ style = SnapText.ChatMessage,
408
+ color = SnapColors.TextPrimary,
409
+ modifier = Modifier
410
+ .widthIn(max = (LocalConfiguration.current.screenWidthDp * 0.75f).dp)
411
+ .clip(RoundedCornerShape(20.dp))
412
+ .background(if (fromMe) SnapColors.Surface2 else SnapColors.Surface1)
413
+ .padding(horizontal = 14.dp, vertical = 10.dp),
414
+ )
415
+ if (!fromMe) Spacer(Modifier.weight(1f).widthIn(min = 60.dp))
416
+ }
417
+ }
418
+
419
+ import androidx.compose.ui.platform.LocalConfiguration
420
+ ```
421
+
422
+ ## 4. Snapchat-Specific Feature: the Chromeless Camera HUD
423
+
424
+ The signature: the app opens to a full-bleed live viewfinder with **no UI frame** — controls float chromelessly in the corners with a drop shadow for legibility over any scene. Above the capture button is the lens carousel (active lens scales 60dp → 72dp with a 3dp yellow ring).
425
+
426
+ ```kotlin
427
+ import androidx.compose.foundation.lazy.LazyRow
428
+ import androidx.compose.material.icons.filled.*
429
+ import androidx.compose.ui.unit.dp
430
+
431
+ @Composable
432
+ fun SnapCameraHUD(
433
+ cameraFeed: @Composable () -> Unit, // your CameraX PreviewView wrapped in AndroidView
434
+ ) {
435
+ var flashOn by remember { mutableStateOf(false) }
436
+ var selectedLens by remember { mutableStateOf(2) }
437
+ var isRecording by remember { mutableStateOf(false) }
438
+ var progress by remember { mutableStateOf(0f) }
439
+ val lenses = listOf("😎", "🎭", "🐶", "😂", "✨")
440
+
441
+ Box(Modifier.fillMaxSize().background(SnapColors.Canvas)) {
442
+ cameraFeed() // edge-to-edge, no frame
443
+
444
+ Column(Modifier.fillMaxSize()) {
445
+ // Top floating HUD
446
+ Row(
447
+ Modifier.fillMaxWidth().padding(16.dp),
448
+ horizontalArrangement = Arrangement.SpaceBetween,
449
+ ) {
450
+ HudIcon(Icons.Filled.AccountCircle)
451
+ Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
452
+ HudIcon(
453
+ if (flashOn) Icons.Filled.FlashOn else Icons.Filled.FlashOff,
454
+ tint = if (flashOn) SnapColors.Yellow else Color.White,
455
+ ) { flashOn = !flashOn }
456
+ HudIcon(Icons.Filled.FlipCameraAndroid)
457
+ HudIcon(Icons.Filled.Search)
458
+ }
459
+ }
460
+
461
+ Spacer(Modifier.weight(1f))
462
+
463
+ LensCarousel(lenses, selectedLens) { selectedLens = it }
464
+ Spacer(Modifier.height(16.dp))
465
+
466
+ Row(
467
+ Modifier.fillMaxWidth().padding(horizontal = 32.dp, vertical = 16.dp),
468
+ horizontalArrangement = Arrangement.SpaceBetween,
469
+ verticalAlignment = Alignment.CenterVertically,
470
+ ) {
471
+ HudIcon(Icons.Filled.PhotoLibrary, size = 32.dp)
472
+ SnapCaptureButton(
473
+ isRecording = isRecording,
474
+ recordProgress = progress,
475
+ onPhoto = {},
476
+ onVideoStart = { isRecording = true },
477
+ onVideoStop = { isRecording = false },
478
+ onFlip = {},
479
+ )
480
+ HudIcon(Icons.AutoMirrored.Filled.Chat, size = 32.dp)
481
+ }
482
+ }
483
+ }
484
+ }
485
+
486
+ @Composable
487
+ fun HudIcon(
488
+ icon: androidx.compose.ui.graphics.vector.ImageVector,
489
+ size: androidx.compose.ui.unit.Dp = 28.dp,
490
+ tint: Color = Color.White,
491
+ onClick: () -> Unit = {},
492
+ ) {
493
+ Box(
494
+ Modifier.size(44.dp).clickableNoRipple(onClick),
495
+ contentAlignment = Alignment.Center,
496
+ ) {
497
+ Icon(
498
+ icon, contentDescription = null, tint = tint,
499
+ modifier = Modifier
500
+ .size(size)
501
+ .graphicsLayer { shadowElevation = 2f }, // legibility over any scene
502
+ )
503
+ }
504
+ }
505
+
506
+ @Composable
507
+ fun LensCarousel(lenses: List<String>, selected: Int, onSelect: (Int) -> Unit) {
508
+ LazyRow(
509
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
510
+ contentPadding = PaddingValues(horizontal = 16.dp),
511
+ modifier = Modifier.fillMaxWidth(),
512
+ ) {
513
+ itemsIndexed(lenses) { i, lens ->
514
+ val active = i == selected
515
+ val s by animateFloatAsState(if (active) 72f else 60f, label = "lensSize")
516
+ Box(
517
+ Modifier
518
+ .size(s.dp)
519
+ .clip(CircleShape)
520
+ .background(SnapColors.Surface2)
521
+ .then(if (active) Modifier.border(3.dp, SnapColors.Yellow, CircleShape) else Modifier)
522
+ .clickableNoRipple { onSelect(i) },
523
+ contentAlignment = Alignment.Center,
524
+ ) { Text(lens, fontSize = (if (active) 32 else 28).sp) }
525
+ }
526
+ }
527
+ }
528
+
529
+ import androidx.compose.animation.core.animateFloatAsState
530
+ import androidx.compose.foundation.layout.PaddingValues
531
+ import androidx.compose.foundation.lazy.itemsIndexed
532
+ import androidx.compose.foundation.clickable
533
+ import androidx.compose.foundation.interaction.MutableInteractionSource
534
+ import androidx.compose.ui.composed
535
+ fun Modifier.clickableNoRipple(onClick: () -> Unit): Modifier = composed {
536
+ clickable(remember { MutableInteractionSource() }, indication = null, onClick = onClick)
537
+ }
538
+ ```
539
+
540
+ ## 5. Navigation — swipe-between-five-screens (NOT a tab bar)
541
+
542
+ Snapchat has no traditional tab bar. iOS uses a paged `TabView`; the Compose equivalent is a `HorizontalPager` with the **Camera centered (page 2)** as the default, plus a minimal indicator strip (translucent over the camera, solid black elsewhere — Android has no live blur).
543
+
544
+ ```kotlin
545
+ import androidx.compose.foundation.pager.HorizontalPager
546
+ import androidx.compose.foundation.pager.rememberPagerState
547
+
548
+ @Composable
549
+ fun SnapRootSwipeNav() {
550
+ val pager = rememberPagerState(initialPage = 2, pageCount = { 5 }) // Camera = 2, the default
551
+
552
+ Box(Modifier.fillMaxSize()) {
553
+ HorizontalPager(state = pager, modifier = Modifier.fillMaxSize()) { page ->
554
+ when (page) {
555
+ 0 -> SnapMapScreen()
556
+ 1 -> ChatListScreen()
557
+ 2 -> SnapCameraHUD(cameraFeed = { /* CameraX preview */ })
558
+ 3 -> StoriesScreen()
559
+ 4 -> SpotlightScreen()
560
+ }
561
+ }
562
+ SnapNavIndicator(
563
+ selected = pager.currentPage,
564
+ overCamera = pager.currentPage == 2,
565
+ modifier = Modifier.align(Alignment.BottomCenter),
566
+ )
567
+ }
568
+ }
569
+
570
+ @Composable
571
+ fun SnapNavIndicator(selected: Int, overCamera: Boolean, modifier: Modifier = Modifier) {
572
+ val icons = listOf(
573
+ Icons.Filled.Map, Icons.AutoMirrored.Filled.Chat, Icons.Filled.CameraAlt,
574
+ Icons.Filled.PlayArrow, Icons.Filled.Diamond,
575
+ )
576
+ Row(
577
+ modifier
578
+ .fillMaxWidth()
579
+ .background(if (overCamera) Color.Black.copy(alpha = 0.5f) else SnapColors.Canvas)
580
+ .height(56.dp),
581
+ verticalAlignment = Alignment.CenterVertically,
582
+ ) {
583
+ icons.forEachIndexed { i, icon ->
584
+ Icon(
585
+ icon, contentDescription = null,
586
+ tint = if (i == selected) Color.White else SnapColors.TextTertiary,
587
+ modifier = Modifier.weight(1f).size(28.dp),
588
+ )
589
+ }
590
+ }
591
+ }
592
+ ```
593
+
594
+ `HorizontalPager` gives the 300ms spring page transition; set `pageSpacing` and rely on the default fling for the rubber-band edge feel. No labels — icons only.
595
+
596
+ ## 6. Motion
597
+
598
+ | Moment | Compose recipe |
599
+ |--------|----------------|
600
+ | Screen swipe (5-screen) | `HorizontalPager` default spring (~300ms) + fling; `HapticFeedbackType.TextHandleMove` on edge resistance |
601
+ | Capture tap (photo) | inner-circle `Animatable` 0.92 → 1.0 `spring(stiffness = 500f)` + white-flash `Box` 100ms + `HapticFeedbackType.LongPress` (soft) |
602
+ | Capture hold (video) | outer arc `drawArc` driven by a 60s `Animatable`/`tween`; `LongPress` on start, soft tick per 1s |
603
+ | Camera flip (double-tap) | shutter icon `rotate` 180° over 400ms + `HapticFeedbackType.TextHandleMove` |
604
+ | Lens swipe/select | `animateFloatAsState` 60dp → 72dp + yellow-ring `fadeIn`; AR overlay cross-fade 200ms |
605
+ | Snap send | preview `slideOutHorizontally { -it }` 300ms + confetti `Canvas`/`Animatable` + `HapticFeedbackType.Confirm` |
606
+ | Streak save | flame `Animatable` 1.0 → 1.3 → 1.0 + "+1 🔥" `offset`/`fadeOut` 600ms + success haptic |
607
+ | Story ring pulse | `rememberInfiniteTransition` opacity 1.0 ↔ 0.7 over 2s (unread only) |
608
+
609
+ ```kotlin
610
+ // Streak-save bounce + floating "+1 🔥"
611
+ @Composable
612
+ fun StreakSaveBurst(trigger: Any) {
613
+ val scale = remember { Animatable(1f) }
614
+ val rise = remember { Animatable(0f) }
615
+ LaunchedEffect(trigger) {
616
+ scale.animateTo(1.3f, spring(dampingRatio = 0.5f)); scale.animateTo(1f, spring())
617
+ rise.animateTo(1f, tween(600))
618
+ }
619
+ Box {
620
+ Text("🔥", Modifier.scale(scale.value), style = SnapText.StreakCount)
621
+ Text(
622
+ "+1 🔥",
623
+ Modifier
624
+ .offset(y = (-20).dp * rise.value)
625
+ .graphicsLayer { alpha = 1f - rise.value },
626
+ style = SnapText.HudLabel,
627
+ color = SnapColors.Yellow,
628
+ )
629
+ }
630
+ }
631
+
632
+ import androidx.compose.foundation.layout.offset
633
+ ```
634
+
635
+ Haptics: prefer `LocalHapticFeedback`. Photo capture = `LongPress` (soft impact), video start = `LongPress` (medium), camera flip / screen-edge / lens = `TextHandleMove`, streak save / snap sent = `HapticFeedbackType.Confirm`. The capture haptic should also pair with a shutter sound. Honor reduce-motion: disable the story-ring pulse and skip the flip-spin while still firing haptics.
636
+
637
+ ## 7. Icons
638
+
639
+ Snapchat uses custom glyphs extensively (ghost logo, capture button is hand-drawn in §3); the closest first-party set is `androidx.compose.material:material-icons-extended`. The ghost logo and bitmoji ship as assets (vector drawable / Coil-loaded). Bitmoji always replaces a generic person icon.
640
+
641
+ | Purpose | SF Symbol (iOS) | Material Icon (Compose) |
642
+ |---------|-----------------|--------------------------|
643
+ | Camera (nav) | `camera.fill` | `Icons.Filled.CameraAlt` |
644
+ | Chat (nav) | `bubble.left.fill` | `Icons.AutoMirrored.Filled.Chat` |
645
+ | Map (nav) | `map.fill` | `Icons.Filled.Map` |
646
+ | Stories (nav) | `play.rectangle.fill` | `Icons.Filled.PlayArrow` |
647
+ | Spotlight (nav) | `diamond.fill` | `Icons.Filled.Diamond` |
648
+ | Memories (HUD) | `photo.stack.fill` | `Icons.Filled.PhotoLibrary` |
649
+ | Flash on | `bolt.fill` | `Icons.Filled.FlashOn` |
650
+ | Flash off | `bolt.slash.fill` | `Icons.Filled.FlashOff` |
651
+ | Camera flip | `arrow.triangle.2.circlepath.camera.fill` | `Icons.Filled.FlipCameraAndroid` |
652
+ | Search | `magnifyingglass` | `Icons.Filled.Search` |
653
+ | Send | `paperplane.fill` | `Icons.AutoMirrored.Filled.Send` |
654
+ | New chat | `square.and.pencil` | `Icons.Filled.Edit` |
655
+ | Profile | `person.crop.circle.fill` (or bitmoji) | `Icons.Filled.AccountCircle` (or bitmoji) |
656
+ | Snap incoming | `arrow.down` in square | `Icons.Filled.ArrowDownward` (in 16dp square) |
657
+ | Snap outgoing | `arrow.up` in square | `Icons.Filled.ArrowUpward` (in 16dp square) |
658
+ | Microphone (audio) | `mic.fill` | `Icons.Filled.Mic` |
659
+ | Sticker | `face.smiling` | `Icons.Filled.AddReaction` |
660
+ | Streak / BFF / birthday | 🔥 / 💛 / 🎂 | emoji glyphs (not icons) |
661
+
662
+ ## 8. Minimum SDK & Accessibility Notes
663
+
664
+ - **minSdk 24** (CameraX + modern motion are comfortable at 24). `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`. The capture button and progress arc are hand-drawn `Canvas` — no extra dependency.
665
+ - **Edge-to-edge**: call `enableEdgeToEdge()`. The camera is **edge-to-edge by design** (`Modifier.fillMaxSize()` + `ignoresSafeArea` equivalent — no insets on the viewfinder). Apply insets only to the floating HUD icons (clear the status bar / Dynamic-Island-equivalent cutout) and the bottom nav strip (clear gesture nav). Capture button sits ~20.dp above the nav strip.
666
+ - **Font scaling**: `sp` honors user scale on chat messages, row names, bios, settings. **Pin camera HUD labels, streak counts, lens labels, timestamps, and story-thumbnail names to fixed sizes** (layout-sensitive) via a fixed-`fontScale` `LocalDensity`.
667
+ - **TalkBack**: every floating HUD icon needs an explicit `contentDescription` ("Flash, off", "Camera, switch to front"). The capture button announces "Snap camera, double tap to capture photo, press and hold to record video". The swipe nav is disorienting for screen readers — provide a rotor/`semantics` "Go to screen" action listing Map / Chat / Camera / Stories / Spotlight as discrete destinations. Bitmoji images are decorative: `Modifier.semantics { hideFromAccessibility() }` (or `contentDescription = null`) and rely on the adjacent name.
668
+ - **Reduce motion**: respect the accessibility setting — disable the story-ring pulse, skip the camera-flip spin and the streak burst, but still fire haptics. **Reduce transparency**: the translucent nav indicator falls back to solid `#000000`.
669
+ - **Alternatives for inaccessible gestures**: long-press-for-video is not screen-reader-operable — provide an explicit "Record video" mode toggle. Flash/Live states must always carry a text label, never color alone.
670
+ - **Contrast**: white on `#000000` is maximum; `#8A8A8F` secondary on black passes AA at 13sp+. The chromeless HUD relies on the drop shadow over arbitrary camera scenes — offer an accessibility "opaque chrome background" toggle that puts a semi-transparent pill behind each icon.
671
+ - **Dynamic color**: do **not** enable Material You `dynamicColorScheme()` — Snap Yellow is an intentionally aggressive fixed brand signal flare, and the snap-type colors (red/purple/blue/green) are a semantic at-a-glance language. Both must be identical regardless of wallpaper.