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,392 @@
1
+ # BeReal (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports BeReal'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 (BeReal's pure-black darkroom, the monochrome no-brand-hue stance, the dual-lens composite, RealMoji reactions) while making everything idiomatic Android — `NavigationBar` instead of a UITabBar, `CameraX` instead of AVFoundation, `sp`/`dp` instead of `pt`.
6
+
7
+ Assumes Compose BOM `2024.09+`, Kotlin `2.0+`, `minSdk 24`, Material 3, [Coil](https://coil-kt.github.io/coil/) `2.6+` for images, and `CameraX` for the dual capture.
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/BeRealColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+
15
+ object BeRealColors {
16
+ // Canvas & Surfaces
17
+ val Canvas = Color(0xFF000000)
18
+ val Surface1 = Color(0xFF1C1C1E)
19
+ val Surface2 = Color(0xFF2C2C2E)
20
+ val Divider = Color(0xFF2C2C2E)
21
+
22
+ // Text
23
+ val TextPrimary = Color(0xFFFFFFFF)
24
+ val TextSecondary = Color(0xFF8E8E93)
25
+ val TextTertiary = Color(0xFF636366)
26
+
27
+ // Accent — intentionally monochrome, no brand hue
28
+ val Accent = Color(0xFFFFFFFF)
29
+ val OnAccent = Color(0xFF000000)
30
+
31
+ // Semantic
32
+ val Late = Color(0xFFFFD60A)
33
+ val Error = Color(0xFFFF453A)
34
+ val Online = Color(0xFF30D158)
35
+ }
36
+ ```
37
+
38
+ Wire it into a Material 3 `darkColorScheme`. BeReal is dark-only by design — the photographic darkroom metaphor depends on true black; do **not** provide a light scheme.
39
+
40
+ ```kotlin
41
+ // ui/theme/Theme.kt
42
+ import androidx.compose.material3.darkColorScheme
43
+ import androidx.compose.material3.MaterialTheme
44
+ import androidx.compose.runtime.Composable
45
+
46
+ private val BeRealScheme = darkColorScheme(
47
+ primary = BeRealColors.Accent,
48
+ onPrimary = BeRealColors.OnAccent, // black on white — intentional inversion
49
+ background = BeRealColors.Canvas,
50
+ onBackground = BeRealColors.TextPrimary,
51
+ surface = BeRealColors.Surface1,
52
+ onSurface = BeRealColors.TextPrimary,
53
+ surfaceVariant = BeRealColors.Surface2,
54
+ outline = BeRealColors.Divider,
55
+ error = BeRealColors.Error,
56
+ )
57
+
58
+ @Composable
59
+ fun BeRealTheme(content: @Composable () -> Unit) =
60
+ MaterialTheme(colorScheme = BeRealScheme, typography = BeRealTypography, content = content)
61
+ ```
62
+
63
+ ## 2. Typography
64
+
65
+ BeReal ships **no custom typeface** — it uses the system font. On Android that is Roboto; reference `FontFamily.Default` so there is nothing to drop in `res/font/`.
66
+
67
+ ```kotlin
68
+ // ui/theme/BeRealType.kt
69
+ import androidx.compose.material3.Typography
70
+ import androidx.compose.ui.text.TextStyle
71
+ import androidx.compose.ui.text.font.FontFamily
72
+ import androidx.compose.ui.text.font.FontWeight
73
+ import androidx.compose.ui.unit.sp
74
+
75
+ private val Sys = FontFamily.Default // BeReal uses the system font, no custom face
76
+
77
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1)
78
+ object BeRealText {
79
+ val Timer = TextStyle(Sys, fontWeight = FontWeight.Bold, fontSize = 24.sp, lineHeight = 26.sp) // use tabular figures via FontFeatureSettings("tnum")
80
+ val ScreenTitle = TextStyle(Sys, fontWeight = FontWeight.Bold, fontSize = 22.sp, lineHeight = 26.sp, letterSpacing = (-0.3).sp)
81
+ val Username = TextStyle(Sys, fontWeight = FontWeight.SemiBold, fontSize = 17.sp, lineHeight = 20.sp, letterSpacing = (-0.2).sp)
82
+ val Caption = TextStyle(Sys, fontWeight = FontWeight.Normal, fontSize = 16.sp, lineHeight = 22.sp)
83
+ val Body = TextStyle(Sys, fontWeight = FontWeight.Normal, fontSize = 15.sp, lineHeight = 21.sp)
84
+ val CommentAuthor= TextStyle(Sys, fontWeight = FontWeight.SemiBold, fontSize = 14.sp, lineHeight = 18.sp)
85
+ val Meta = TextStyle(Sys, fontWeight = FontWeight.Normal, fontSize = 13.sp, lineHeight = 17.sp)
86
+ val LateBadge = TextStyle(Sys, fontWeight = FontWeight.Bold, fontSize = 12.sp, lineHeight = 14.sp, letterSpacing = 0.2.sp)
87
+ val Button = TextStyle(Sys, fontWeight = FontWeight.SemiBold, fontSize = 17.sp, lineHeight = 20.sp, letterSpacing = (-0.2).sp)
88
+ val Tab = TextStyle(Sys, fontWeight = FontWeight.SemiBold, fontSize = 10.sp, lineHeight = 12.sp)
89
+ val Retake = TextStyle(Sys, fontWeight = FontWeight.SemiBold, fontSize = 11.sp, lineHeight = 13.sp)
90
+ }
91
+
92
+ // Map onto Material 3 slots so stock components inherit the system-font, dark identity
93
+ val BeRealTypography = Typography(
94
+ headlineMedium = BeRealText.ScreenTitle,
95
+ titleMedium = BeRealText.Username,
96
+ bodyMedium = BeRealText.Body,
97
+ labelSmall = BeRealText.Tab,
98
+ )
99
+ ```
100
+
101
+ ## 3. Signature Components
102
+
103
+ ### Dual-Lens Composite Card (the signature)
104
+
105
+ ```kotlin
106
+ import androidx.compose.foundation.gestures.detectDragGestures
107
+ import androidx.compose.foundation.layout.*
108
+ import androidx.compose.runtime.*
109
+ import androidx.compose.ui.Alignment
110
+ import androidx.compose.ui.Modifier
111
+ import androidx.compose.ui.draw.clip
112
+ import androidx.compose.ui.draw.scale
113
+ import androidx.compose.ui.draw.shadow
114
+ import androidx.compose.ui.input.pointer.pointerInput
115
+ import androidx.compose.ui.unit.dp
116
+ import androidx.compose.foundation.shape.RoundedCornerShape
117
+ import coil.compose.AsyncImage
118
+
119
+ enum class SelfieCorner { TopStart, TopEnd, BottomStart, BottomEnd }
120
+
121
+ @Composable
122
+ fun DualLensCard(backUrl: String, frontUrl: String, modifier: Modifier = Modifier) {
123
+ var corner by remember { mutableStateOf(SelfieCorner.TopStart) }
124
+ var lifted by remember { mutableStateOf(false) }
125
+ val scale by androidx.compose.animation.core.animateFloatAsState(
126
+ if (lifted) 1.05f else 1f,
127
+ androidx.compose.animation.core.spring(dampingRatio = 0.75f, stiffness = 300f),
128
+ label = "selfieLift",
129
+ )
130
+
131
+ Box(
132
+ modifier
133
+ .fillMaxWidth()
134
+ .aspectRatio(3f / 4f)
135
+ .shadow(24.dp, RoundedCornerShape(18.dp), spotColor = androidx.compose.ui.graphics.Color.Black.copy(0.6f))
136
+ .clip(RoundedCornerShape(18.dp)),
137
+ ) {
138
+ AsyncImage(model = backUrl, contentDescription = "BeReal back photo",
139
+ modifier = Modifier.fillMaxSize())
140
+
141
+ AsyncImage(
142
+ model = frontUrl,
143
+ contentDescription = "BeReal selfie",
144
+ modifier = Modifier
145
+ .align(corner.toAlignment())
146
+ .padding(12.dp)
147
+ .size(100.dp, 134.dp)
148
+ .scale(scale)
149
+ .shadow(if (lifted) 18.dp else 0.dp, RoundedCornerShape(14.dp))
150
+ .clip(RoundedCornerShape(14.dp))
151
+ .pointerInput(Unit) {
152
+ detectDragGestures(
153
+ onDragStart = { lifted = true },
154
+ onDragEnd = {
155
+ lifted = false
156
+ corner = SelfieCorner.entries.random()
157
+ },
158
+ ) { _, _ -> }
159
+ },
160
+ )
161
+ }
162
+ }
163
+
164
+ private fun SelfieCorner.toAlignment() = when (this) {
165
+ SelfieCorner.TopStart -> Alignment.TopStart
166
+ SelfieCorner.TopEnd -> Alignment.TopEnd
167
+ SelfieCorner.BottomStart -> Alignment.BottomStart
168
+ SelfieCorner.BottomEnd -> Alignment.BottomEnd
169
+ }
170
+ ```
171
+
172
+ ### Capture Button (Dual Shutter)
173
+
174
+ ```kotlin
175
+ import androidx.compose.foundation.interaction.MutableInteractionSource
176
+ import androidx.compose.foundation.interaction.collectIsPressedAsState
177
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
178
+ import androidx.compose.ui.platform.LocalHapticFeedback
179
+ import kotlinx.coroutines.delay
180
+ import kotlinx.coroutines.launch
181
+
182
+ @Composable
183
+ fun CaptureButton(onCapture: () -> Unit, modifier: Modifier = Modifier) {
184
+ val interaction = remember { MutableInteractionSource() }
185
+ val pressed by interaction.collectIsPressedAsState()
186
+ val haptics = LocalHapticFeedback.current
187
+ val scope = rememberCoroutineScope()
188
+ val scale by androidx.compose.animation.core.animateFloatAsState(if (pressed) 0.92f else 1f, label = "capScale")
189
+ val disc by androidx.compose.animation.core.animateDpAsState(if (pressed) 64.dp else 0.dp, label = "capDisc")
190
+
191
+ Box(
192
+ modifier
193
+ .size(76.dp)
194
+ .scale(scale)
195
+ .clip(androidx.compose.foundation.shape.CircleShape)
196
+ .border(4.dp, BeRealColors.Accent, androidx.compose.foundation.shape.CircleShape)
197
+ .clickable(interaction, indication = null) {
198
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // heavy ≈ back camera
199
+ onCapture()
200
+ scope.launch {
201
+ delay(500)
202
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove) // soft ≈ front
203
+ }
204
+ },
205
+ contentAlignment = Alignment.Center,
206
+ ) {
207
+ Box(Modifier.size(disc).clip(androidx.compose.foundation.shape.CircleShape).background(BeRealColors.Accent))
208
+ }
209
+ }
210
+ ```
211
+
212
+ ### Primary / Secondary Button
213
+
214
+ ```kotlin
215
+ enum class BeRealBtn { Filled, Outline }
216
+
217
+ @Composable
218
+ fun BeRealButton(text: String, onClick: () -> Unit, style: BeRealBtn = BeRealBtn.Filled, modifier: Modifier = Modifier) {
219
+ val interaction = remember { MutableInteractionSource() }
220
+ val pressed by interaction.collectIsPressedAsState()
221
+ val scale by androidx.compose.animation.core.animateFloatAsState(if (pressed) 0.97f else 1f, label = "btn")
222
+ val filled = style == BeRealBtn.Filled
223
+
224
+ Box(
225
+ modifier
226
+ .scale(scale)
227
+ .clip(androidx.compose.foundation.shape.CircleShape)
228
+ .then(
229
+ if (filled) Modifier.background(BeRealColors.Accent)
230
+ else Modifier.border(1.dp, BeRealColors.TextPrimary.copy(alpha = 0.4f), androidx.compose.foundation.shape.CircleShape)
231
+ )
232
+ .clickable(interaction, indication = null, onClick = onClick)
233
+ .padding(horizontal = if (filled) 32.dp else 24.dp, vertical = if (filled) 14.dp else 12.dp),
234
+ contentAlignment = Alignment.Center,
235
+ ) {
236
+ Text(text, style = BeRealText.Button,
237
+ color = if (filled) BeRealColors.OnAccent else BeRealColors.TextPrimary)
238
+ }
239
+ }
240
+ ```
241
+
242
+ ### Countdown Banner & Late Badge
243
+
244
+ ```kotlin
245
+ import androidx.compose.ui.text.font.FontFeature
246
+ import androidx.compose.ui.text.style.TextAlign
247
+
248
+ @Composable
249
+ fun CountdownBanner(remaining: String, modifier: Modifier = Modifier) {
250
+ // Android has no live blur — use a 60%-opaque black pill with the amber border
251
+ Box(
252
+ modifier
253
+ .fillMaxWidth()
254
+ .clip(androidx.compose.foundation.shape.CircleShape)
255
+ .background(androidx.compose.ui.graphics.Color.Black.copy(alpha = 0.6f))
256
+ .border(1.dp, BeRealColors.Late.copy(alpha = 0.4f), androidx.compose.foundation.shape.CircleShape)
257
+ .padding(horizontal = 20.dp, vertical = 12.dp),
258
+ contentAlignment = Alignment.Center,
259
+ ) {
260
+ Text(
261
+ "⏰ $remaining left to capture a BeReal",
262
+ style = BeRealText.Timer.copy(fontFeatureSettings = "tnum"), // tabular digits
263
+ color = BeRealColors.Late,
264
+ textAlign = TextAlign.Center,
265
+ )
266
+ }
267
+ }
268
+
269
+ @Composable
270
+ fun LateBadge(text: String) =
271
+ Text("⚠ $text", style = BeRealText.LateBadge, color = BeRealColors.Late)
272
+ ```
273
+
274
+ ### RealMoji Reaction Cluster
275
+
276
+ ```kotlin
277
+ @Composable
278
+ fun RealMojiCluster(selfieUrls: List<String>, onAdd: () -> Unit, modifier: Modifier = Modifier) {
279
+ Row(modifier, verticalAlignment = Alignment.CenterVertically) {
280
+ selfieUrls.forEachIndexed { i, url ->
281
+ AsyncImage(
282
+ model = url,
283
+ contentDescription = "Reaction", // never a count — reactions are faces
284
+ modifier = Modifier
285
+ .offset(x = if (i == 0) 0.dp else (-8 * i).dp) // overlap by 8dp
286
+ .size(30.dp)
287
+ .clip(androidx.compose.foundation.shape.CircleShape)
288
+ .border(2.dp, androidx.compose.ui.graphics.Color.Black, androidx.compose.foundation.shape.CircleShape),
289
+ )
290
+ }
291
+ Box(
292
+ Modifier
293
+ .padding(start = 12.dp)
294
+ .size(30.dp)
295
+ .clip(androidx.compose.foundation.shape.CircleShape)
296
+ .border(1.5.dp, BeRealColors.TextPrimary.copy(alpha = 0.6f), androidx.compose.foundation.shape.CircleShape)
297
+ .clickable(onClick = onAdd),
298
+ contentAlignment = Alignment.Center,
299
+ ) { Text("+", style = BeRealText.Button, color = BeRealColors.TextPrimary) }
300
+ }
301
+ }
302
+ ```
303
+
304
+ ## 4. Distinctive System — Selfie Corner-Snap in Compose
305
+
306
+ The front selfie inset is the soul of BeReal. `DualLensCard` (above) wires `detectDragGestures`: drag start sets `lifted = true` (scale animates to 1.05 via `spring(dampingRatio = 0.75f)`), drag end snaps `corner` to a `SelfieCorner` and the `Alignment` recomposes. A non-drag tap on the selfie swaps which camera is full-bleed — animate a `Crossfade` between the two `AsyncImage`s. Keep the snap spring at `dampingRatio = 0.75f, stiffness = 300f` to match the iOS feel.
307
+
308
+ ## 5. Bottom Navigation (Tab Bar)
309
+
310
+ Use Material 3 `NavigationBar`. BeReal's iOS tab bar is opaque true-black with **no blur** — Android has no first-class live blur anyway, so a solid `#000000` surface is an exact match. Active tint is **white** (BeReal has no brand hue); kill the Material indicator pill.
311
+
312
+ ```kotlin
313
+ @Composable
314
+ fun BeRealBottomBar(selected: Int, onSelect: (Int) -> Unit) {
315
+ NavigationBar(containerColor = BeRealColors.Canvas, tonalElevation = 0.dp) {
316
+ val items = listOf(
317
+ "Friends" to Icons.Filled.People,
318
+ "Official" to Icons.Filled.Star,
319
+ "Search" to Icons.Filled.Search,
320
+ "Profile" to Icons.Filled.AccountCircle,
321
+ )
322
+ items.forEachIndexed { i, (label, icon) ->
323
+ NavigationBarItem(
324
+ selected = selected == i,
325
+ onClick = { onSelect(i) },
326
+ icon = { Icon(icon, contentDescription = label, modifier = Modifier.size(26.dp)) },
327
+ label = { Text(label, style = BeRealText.Tab) },
328
+ colors = NavigationBarItemDefaults.colors(
329
+ selectedIconColor = BeRealColors.TextPrimary, // white, no brand hue
330
+ selectedTextColor = BeRealColors.TextPrimary,
331
+ unselectedIconColor = BeRealColors.TextPrimary.copy(alpha = 0.45f),
332
+ unselectedTextColor = BeRealColors.TextPrimary.copy(alpha = 0.45f),
333
+ indicatorColor = androidx.compose.ui.graphics.Color.Transparent, // BeReal has no pill
334
+ ),
335
+ )
336
+ }
337
+ }
338
+ }
339
+ ```
340
+
341
+ ## 6. Motion
342
+
343
+ | Moment | Compose recipe |
344
+ |--------|----------------|
345
+ | Dual-shutter capture | white-flash overlay (`AnimatedVisibility` 120ms) + `HapticFeedbackType.LongPress`, then `delay(500)` + soft haptic for the front lens |
346
+ | Camera flip | `graphicsLayer { rotationY = … }` animated 0 → 180 over 350ms `tween`, light haptic |
347
+ | Selfie drag-snap | `animateFloatAsState`/alignment recompose with `spring(dampingRatio = 0.75f, stiffness = 300f)` |
348
+ | RealMoji pop | `Animatable` keyframes 0 → 1.2 → 1 over 280ms |
349
+ | Feed un-blur | friends' cards `Modifier.blur(30.dp)` → `0.dp` once you post, `animateDpAsState` 400ms |
350
+
351
+ ```kotlin
352
+ // Camera flip
353
+ val rot by animateFloatAsState(if (flipped) 180f else 0f, tween(350), label = "flip")
354
+ Box(Modifier.graphicsLayer { rotationY = rot; cameraDistance = 12f * density }) { /* viewfinder */ }
355
+
356
+ // RealMoji pop
357
+ val pop = remember { Animatable(0f) }
358
+ LaunchedEffect(Unit) {
359
+ pop.animateTo(1.2f, tween(160)); pop.animateTo(1f, spring())
360
+ }
361
+ ```
362
+
363
+ Haptics: prefer `LocalHapticFeedback`. For the heavy capture impact use `LocalView.current.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)` or a `Vibrator` `VibrationEffect.createOneShot(20, 255)`; follow with a lighter `CONTEXT_CLICK` ~500ms later for the front camera.
364
+
365
+ ## 7. Icons
366
+
367
+ BeReal uses simple glyphs; the closest first-party set is `androidx.compose.material:material-icons-extended`.
368
+
369
+ | Purpose | SF Symbol (iOS) | Material Icon (Compose) |
370
+ |---------|-----------------|--------------------------|
371
+ | Camera flip | `arrow.triangle.2.circlepath.camera` | `Icons.Filled.FlipCameraIos` |
372
+ | Flash | `bolt.fill` / `bolt.slash.fill` | `Icons.Filled.FlashOn` / `Icons.Filled.FlashOff` |
373
+ | Late badge | `exclamationmark.triangle.fill` | `Icons.Filled.Warning` |
374
+ | Add RealMoji | `plus` | `Icons.Filled.Add` |
375
+ | Comments | `bubble.left` | `Icons.Outlined.ChatBubbleOutline` |
376
+ | Share | `square.and.arrow.up` | `Icons.Filled.IosShare` |
377
+ | More | `ellipsis` | `Icons.Filled.MoreHoriz` |
378
+ | Friends (tab) | `person.2.fill` | `Icons.Filled.People` |
379
+ | Official (tab) | `star.circle.fill` | `Icons.Filled.Star` |
380
+ | Search (tab) | `magnifyingglass` | `Icons.Filled.Search` |
381
+ | Profile (tab) | `person.crop.circle` | `Icons.Filled.AccountCircle` |
382
+ | BTS video | `play.rectangle.on.rectangle` | `Icons.Filled.Collections` |
383
+
384
+ ## 8. Minimum SDK & Accessibility Notes
385
+
386
+ - **minSdk 24** (Compose floor is 21; `CameraX` dual capture + modern motion are comfortable at 24). `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`.
387
+ - **Edge-to-edge**: call `enableEdgeToEdge()`; the pure-black canvas wants light-content system bars via `WindowCompat`. Let the dual-lens card draw edge-to-edge horizontally (`Modifier.fillMaxWidth()`, no inset) while keeping the tab bar inside `systemBars` insets.
388
+ - **Font scaling**: `sp` honors the user's font scale — keep it on usernames, captions, comments. Pin the countdown (`fontFeatureSettings = "tnum"` and a fixed size), late badge, retake count, and tab labels by deriving from `dp` or a `CompositionLocalProvider(LocalDensity …, fontScale = 1f)`.
389
+ - **TalkBack**: set `contentDescription` on the dual-lens card ("jordan's BeReal, 2 hours late"); mark the selfie as a draggable element with a custom `stateDescription`; announce RealMojis as "Reaction from <name>" and **never** a numeric count — there is none.
390
+ - **Touch targets**: Material guidance is 48.dp minimum. The 76.dp capture button is well clear; give the 30.dp RealMoji `+` a 48.dp hit area via padding.
391
+ - **Contrast**: `#8E8E93` on `#000000` passes WCAG AA at 13sp+. The amber `#FFD60A` on black is high-contrast — reserve it for lateness/urgency only.
392
+ - **Dynamic color**: do **not** enable Material You `dynamicDarkColorScheme()` — BeReal's identity is the fixed pure-black canvas and the deliberate *absence* of a brand hue, regardless of wallpaper.
@@ -0,0 +1,299 @@
1
+ # BeReal (iOS) — Expo / React Native Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file translates BeReal's visual language into paste-ready Expo / React Native code: a design-token module, themed components, and Reanimated snippets.
4
+
5
+ Assumes Expo SDK 51+ with `expo-router`, `expo-font`, `expo-haptics`, `expo-blur`, and `react-native-reanimated` v3.
6
+
7
+ ## 1. Color Tokens
8
+
9
+ ```ts
10
+ // theme/colors.ts
11
+ export const colors = {
12
+ canvas: '#000000',
13
+ surface1: '#1C1C1E',
14
+ surface2: '#2C2C2E',
15
+ divider: '#2C2C2E',
16
+
17
+ textPrimary: '#FFFFFF',
18
+ textSecondary: '#8E8E93',
19
+ textTertiary: '#636366',
20
+
21
+ accent: '#FFFFFF', // no brand hue — white is the verb
22
+ onAccent: '#000000',
23
+
24
+ late: '#FFD60A',
25
+ error: '#FF453A',
26
+ online: '#30D158',
27
+ } as const;
28
+
29
+ export type BeRealColor = keyof typeof colors;
30
+ ```
31
+
32
+ ## 2. Typography
33
+
34
+ BeReal uses the system font (SF Pro on iOS) — no custom face to load. Use `System` and enable tabular figures on the countdown via `fontVariant`.
35
+
36
+ ```ts
37
+ // theme/typography.ts
38
+ import type { TextStyle } from 'react-native';
39
+
40
+ const base = { color: '#FFFFFF' } satisfies TextStyle;
41
+
42
+ export const typography = {
43
+ timer: { ...base, fontSize: 24, lineHeight: 26, fontWeight: '700',
44
+ fontVariant: ['tabular-nums'] as const },
45
+ screenTitle: { ...base, fontSize: 22, lineHeight: 26, fontWeight: '700', letterSpacing: -0.3 },
46
+ username: { ...base, fontSize: 17, lineHeight: 20, fontWeight: '600', letterSpacing: -0.2 },
47
+ caption: { ...base, fontSize: 16, lineHeight: 22, fontWeight: '400' },
48
+ body: { ...base, fontSize: 15, lineHeight: 21, fontWeight: '400' },
49
+ commentAuthor:{ ...base, fontSize: 14, lineHeight: 18, fontWeight: '600' },
50
+ meta: { fontSize: 13, lineHeight: 17, fontWeight: '400', color: '#8E8E93' },
51
+ lateBadge: { fontSize: 12, lineHeight: 14, fontWeight: '700', color: '#FFD60A', letterSpacing: 0.2 },
52
+ button: { fontSize: 17, lineHeight: 20, fontWeight: '600', letterSpacing: -0.2 },
53
+ tab: { fontSize: 10, lineHeight: 12, fontWeight: '600' },
54
+ retake: { ...base, fontSize: 11, lineHeight: 13, fontWeight: '600' },
55
+ } satisfies Record<string, TextStyle>;
56
+ ```
57
+
58
+ ## 3. Signature Components
59
+
60
+ ### Dual-Lens Composite Card (the signature)
61
+
62
+ ```tsx
63
+ // components/DualLensCard.tsx
64
+ import { Image, View } from 'react-native';
65
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
66
+ import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
67
+
68
+ const CORNERS = [
69
+ { top: 12, left: 12 }, { top: 12, right: 12 },
70
+ { bottom: 12, left: 12 }, { bottom: 12, right: 12 },
71
+ ] as const;
72
+
73
+ export function DualLensCard({ backUri, frontUri }: { backUri: string; frontUri: string }) {
74
+ const lift = useSharedValue(1);
75
+ const corner = useSharedValue(0);
76
+
77
+ const longPress = Gesture.LongPress().minDuration(200)
78
+ .onStart(() => (lift.value = withSpring(1.05)));
79
+ const drag = Gesture.Pan()
80
+ .onEnd(() => {
81
+ lift.value = withSpring(1);
82
+ corner.value = Math.floor(Math.random() * 4);
83
+ });
84
+ const gesture = Gesture.Simultaneous(longPress, drag);
85
+
86
+ const selfieStyle = useAnimatedStyle(() => ({
87
+ transform: [{ scale: lift.value }],
88
+ ...CORNERS[corner.value],
89
+ }));
90
+
91
+ return (
92
+ <View style={{ width: '100%', aspectRatio: 3 / 4, borderRadius: 18,
93
+ shadowColor: '#000', shadowOpacity: 0.6, shadowRadius: 24,
94
+ shadowOffset: { width: 0, height: 8 } }}>
95
+ <Image source={{ uri: backUri }} style={{ flex: 1, borderRadius: 18 }} />
96
+ <GestureDetector gesture={gesture}>
97
+ <Animated.View style={[{ position: 'absolute', width: 100, height: 134,
98
+ borderRadius: 14, borderWidth: 2, borderColor: '#000', overflow: 'hidden' }, selfieStyle]}>
99
+ <Image source={{ uri: frontUri }} style={{ flex: 1 }} />
100
+ </Animated.View>
101
+ </GestureDetector>
102
+ </View>
103
+ );
104
+ }
105
+ ```
106
+
107
+ ### Capture Button (Dual Shutter)
108
+
109
+ ```tsx
110
+ // components/CaptureButton.tsx
111
+ import { Pressable } from 'react-native';
112
+ import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
113
+ import * as Haptics from 'expo-haptics';
114
+
115
+ export function CaptureButton({ onCapture }: { onCapture: () => void }) {
116
+ const scale = useSharedValue(1);
117
+ const fill = useSharedValue(0);
118
+ const ring = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }] }));
119
+ const disc = useAnimatedStyle(() => ({ width: fill.value, height: fill.value }));
120
+
121
+ return (
122
+ <Pressable
123
+ onPressIn={() => { scale.value = withSpring(0.92); fill.value = withSpring(64); }}
124
+ onPressOut={() => { scale.value = withSpring(1); fill.value = withSpring(0); }}
125
+ onPress={async () => {
126
+ await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy); // back camera
127
+ onCapture();
128
+ setTimeout(() => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Soft), 500); // front
129
+ }}
130
+ >
131
+ <Animated.View style={[{ width: 76, height: 76, borderRadius: 38,
132
+ borderWidth: 4, borderColor: '#FFF', alignItems: 'center', justifyContent: 'center' }, ring]}>
133
+ <Animated.View style={[{ backgroundColor: '#FFF', borderRadius: 32 }, disc]} />
134
+ </Animated.View>
135
+ </Pressable>
136
+ );
137
+ }
138
+ ```
139
+
140
+ ### Primary / Secondary Button
141
+
142
+ ```tsx
143
+ // components/BeRealButton.tsx
144
+ import { Pressable, Text } from 'react-native';
145
+ import { colors } from '../theme/colors';
146
+ import { typography } from '../theme/typography';
147
+
148
+ export function BeRealButton({
149
+ title, variant = 'filled', onPress,
150
+ }: { title: string; variant?: 'filled' | 'outline'; onPress: () => void }) {
151
+ const filled = variant === 'filled';
152
+ return (
153
+ <Pressable
154
+ onPress={onPress}
155
+ style={({ pressed }) => ({
156
+ paddingVertical: filled ? 14 : 12,
157
+ paddingHorizontal: filled ? 32 : 24,
158
+ borderRadius: 500,
159
+ backgroundColor: filled ? colors.accent : 'transparent',
160
+ borderWidth: filled ? 0 : 1,
161
+ borderColor: 'rgba(255,255,255,0.4)',
162
+ opacity: pressed ? 0.85 : 1,
163
+ transform: [{ scale: pressed ? 0.97 : 1 }],
164
+ })}
165
+ >
166
+ <Text style={[typography.button, { color: filled ? colors.onAccent : '#fff' }]}>{title}</Text>
167
+ </Pressable>
168
+ );
169
+ }
170
+ ```
171
+
172
+ ### Countdown Banner & Late Badge
173
+
174
+ ```tsx
175
+ import { Text, View } from 'react-native';
176
+ import { BlurView } from 'expo-blur';
177
+ import { colors } from '../theme/colors';
178
+ import { typography } from '../theme/typography';
179
+
180
+ export function CountdownBanner({ remaining }: { remaining: string }) {
181
+ return (
182
+ <BlurView intensity={40} tint="dark"
183
+ style={{ borderRadius: 500, overflow: 'hidden',
184
+ borderWidth: 1, borderColor: 'rgba(255,214,10,0.4)',
185
+ paddingVertical: 12, paddingHorizontal: 20, backgroundColor: 'rgba(0,0,0,0.5)' }}>
186
+ <Text style={[typography.timer, { textAlign: 'center' }]}>⏰ {remaining} left to capture a BeReal</Text>
187
+ </BlurView>
188
+ );
189
+ }
190
+
191
+ export function LateBadge({ text }: { text: string }) {
192
+ return <Text style={typography.lateBadge}>⚠ {text}</Text>;
193
+ }
194
+ ```
195
+
196
+ ### RealMoji Reaction Cluster
197
+
198
+ ```tsx
199
+ // components/RealMojiCluster.tsx — selfie photos, never emoji, never counts
200
+ import { Image, Pressable, Text, View } from 'react-native';
201
+
202
+ export function RealMojiCluster({ selfies, onAdd }: { selfies: string[]; onAdd: () => void }) {
203
+ return (
204
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
205
+ {selfies.map((uri, i) => (
206
+ <Image key={i} source={{ uri }}
207
+ style={{ width: 30, height: 30, borderRadius: 15, borderWidth: 2,
208
+ borderColor: '#000', marginLeft: i === 0 ? 0 : -8 }} />
209
+ ))}
210
+ <Pressable onPress={onAdd}
211
+ style={{ width: 30, height: 30, borderRadius: 15, borderWidth: 1.5,
212
+ borderStyle: 'dashed', borderColor: 'rgba(255,255,255,0.6)',
213
+ alignItems: 'center', justifyContent: 'center', marginLeft: 12 }}>
214
+ <Text style={{ color: '#fff', fontSize: 14, fontWeight: '600' }}>+</Text>
215
+ </Pressable>
216
+ </View>
217
+ );
218
+ }
219
+ ```
220
+
221
+ ## 4. Distinctive System — Selfie Corner-Snap
222
+
223
+ The front selfie inset is the soul of BeReal. The `DualLensCard` above wires the full long-press → drag → spring-snap. Snap spring: `withSpring(target, { damping: 14, stiffness: 180 })`. A tap (not drag) on the selfie swaps which camera is full-bleed via a cross-fade — drive a shared `progress` value between the two `Image`s.
224
+
225
+ ## 5. Tab Bar
226
+
227
+ BeReal's tab bar is opaque true-black — **no blur**, the canvas continues. Active tint is white.
228
+
229
+ ```tsx
230
+ // app/(tabs)/_layout.tsx
231
+ import { Tabs } from 'expo-router';
232
+ import Ionicons from '@expo/vector-icons/Ionicons';
233
+ import { colors } from '../../theme/colors';
234
+
235
+ export default function TabsLayout() {
236
+ return (
237
+ <Tabs
238
+ screenOptions={{
239
+ tabBarActiveTintColor: '#FFFFFF',
240
+ tabBarInactiveTintColor: 'rgba(255,255,255,0.45)',
241
+ tabBarStyle: { backgroundColor: '#000000', borderTopColor: 'rgba(255,255,255,0.08)', borderTopWidth: 0.5 },
242
+ tabBarLabelStyle: { fontSize: 10, fontWeight: '600' },
243
+ }}
244
+ >
245
+ <Tabs.Screen name="index" options={{ title: 'Friends', tabBarIcon: ({ color }) => <Ionicons name="people" size={26} color={color} /> }} />
246
+ <Tabs.Screen name="official" options={{ title: 'Official', tabBarIcon: ({ color }) => <Ionicons name="star" size={26} color={color} /> }} />
247
+ <Tabs.Screen name="search" options={{ title: 'Search', tabBarIcon: ({ color }) => <Ionicons name="search" size={26} color={color} /> }} />
248
+ <Tabs.Screen name="profile" options={{ title: 'Profile', tabBarIcon: ({ color }) => <Ionicons name="person-circle" size={26} color={color} /> }} />
249
+ </Tabs>
250
+ );
251
+ }
252
+ ```
253
+
254
+ ## 6. Motion
255
+
256
+ ```tsx
257
+ // Dual-shutter capture: heavy then soft ~0.5s later (see CaptureButton)
258
+ await Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy);
259
+ setTimeout(() => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Soft), 500);
260
+
261
+ // Camera flip: 180° rotateY over 0.35s
262
+ const flip = useSharedValue(0);
263
+ const flipStyle = useAnimatedStyle(() => ({ transform: [{ rotateY: `${flip.value}deg` }] }));
264
+ flip.value = withTiming(flipped ? 180 : 0, { duration: 350 });
265
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
266
+
267
+ // RealMoji pop: 0 → 1.2 → 1 over 280ms
268
+ scale.value = withSequence(withTiming(1.2, { duration: 160 }), withSpring(1));
269
+
270
+ // Friends' BeReals blurred until you post — animate a BlurView intensity 30 → 0 over 0.4s
271
+ ```
272
+
273
+ ## 7. Icon Library
274
+
275
+ Use `@expo/vector-icons` (Ionicons). Map to BeReal's SF Symbol equivalents:
276
+
277
+ | Purpose | SF Symbol (iOS) | Ionicons |
278
+ |---------|-----------------|----------|
279
+ | Camera flip | `arrow.triangle.2.circlepath.camera` | `camera-reverse` |
280
+ | Flash | `bolt.fill` / `bolt.slash.fill` | `flash` / `flash-off` |
281
+ | Late badge | `exclamationmark.triangle.fill` | `warning` |
282
+ | Add RealMoji | `plus` | `add` |
283
+ | Comments | `bubble.left` | `chatbubble-outline` |
284
+ | Share | `square.and.arrow.up` | `share-outline` |
285
+ | More | `ellipsis` | `ellipsis-horizontal` |
286
+ | Friends (tab) | `person.2.fill` | `people` |
287
+ | Official (tab) | `star.circle.fill` | `star` |
288
+ | Search (tab) | `magnifyingglass` | `search` |
289
+ | Profile (tab) | `person.crop.circle` | `person-circle` |
290
+ | BTS video | `play.rectangle.on.rectangle` | `albums` |
291
+
292
+ ## 8. Platform Notes
293
+
294
+ - **iOS-only feel**: BeReal's tab bar is opaque true-black with no blur — do **not** add `expo-blur` to the tab bar; only the countdown pill uses a `BlurView`. Android matches naturally (solid black).
295
+ - **Status bar**: `<StatusBar style="light" />` from `expo-status-bar` globally — the pure-black canvas requires light content
296
+ - **Safe area**: wrap screens in `SafeAreaView` from `react-native-safe-area-context`; the dual-lens card intentionally goes edge-to-edge horizontally (ignore left/right insets for it)
297
+ - **Tabular numerals**: set `fontVariant: ['tabular-nums']` on the countdown so `2:00 → 1:59` doesn't shift; pin `allowFontScaling={false}` on the timer
298
+ - **Camera**: use `expo-camera` with `facing` toggled to capture both lenses in sequence (~0.5s apart) — the dual exposure is the product
299
+ - **Accessibility**: add `accessibilityRole="button"` + `accessibilityLabel="Capture BeReal"` on the shutter; group the dual-lens card text and never expose a reaction count (there is none)