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,618 @@
1
+ # X (Twitter) (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports X's visual language to **Android with Jetpack Compose (Material 3)**: a color token object, a `Typography` set, paste-ready `@Composable`s, `Modifier`s, the per-action color micro-animations, 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 (X's true-black OLED canvas, hairline-separated feed, single-blue structural accent, the three 1:1 action colors, the like-burst micro-interaction) while making everything idiomatic Android — `NavigationBar` instead of a UITabBar, `HorizontalDivider` hairlines instead of card surfaces, a translucent `Surface` instead of `.regularMaterial` blur, `sp`/`dp` instead of `pt`. The app is true-black-first with dim and light alternates; all three are wired below.
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 avatars and post media. No color extraction — X's palette is fixed brand chrome.
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/XColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+
15
+ object XColors {
16
+ // Canvas & surfaces (dark / default)
17
+ val Canvas = Color(0xFF000000) // true-black OLED
18
+ val Surface1 = Color(0xFF16181C)
19
+ val Surface2 = Color(0xFF1E2024)
20
+ val Divider = Color(0xFF2F3336) // the signature 1pt hairline
21
+ val DimCanvas = Color(0xFF15202B)
22
+ val DimSurface1 = Color(0xFF192734)
23
+ val DimDivider = Color(0xFF38444D)
24
+
25
+ // Canvas & surfaces (light)
26
+ val LightCanvas = Color(0xFFFFFFFF)
27
+ val LightSurface1 = Color(0xFFF7F9F9)
28
+ val LightSurface2 = Color(0xFFEFF3F4)
29
+
30
+ // Text
31
+ val TextPrimaryDark = Color(0xFFE7E9EA) // warm off-white, not pure white
32
+ val TextPrimaryLight = Color(0xFF0F1419)
33
+ val TextSecondaryDark = Color(0xFF71767B)
34
+ val TextSecondaryLight = Color(0xFF536471)
35
+
36
+ // Brand / action
37
+ val Blue = Color(0xFF1D9BF0) // links, replies, active underline, verified
38
+ val BluePressed = Color(0xFF1A8CD8)
39
+ val RepostGreen = Color(0xFF00BA7C)
40
+ val LikePink = Color(0xFFF91880) // not red — saturated magenta-pink
41
+ val VerifiedGold = Color(0xFFEAB308)
42
+ val VerifiedGray = Color(0xFF829AAB)
43
+ val ErrorRed = Color(0xFFF4212E)
44
+ val SpacesPurple = Color(0xFF7856FF)
45
+ }
46
+ ```
47
+
48
+ X opens **dark (true black)** for new users, with dim and light alternates. Wire the dark scheme as the default; `primary` is the structural blue. Note the **active tab tint is the stark off-white `#E7E9EA`, not blue** — blue is reserved for links/replies/verified/the feed-filter underline.
49
+
50
+ ```kotlin
51
+ // ui/theme/Theme.kt
52
+ import androidx.compose.material3.darkColorScheme
53
+ import androidx.compose.material3.lightColorScheme
54
+ import androidx.compose.material3.MaterialTheme
55
+ import androidx.compose.runtime.Composable
56
+ import androidx.compose.foundation.isSystemInDarkTheme
57
+
58
+ private val XDark = darkColorScheme(
59
+ primary = XColors.Blue,
60
+ onPrimary = XColors.TextPrimaryDark,
61
+ background = XColors.Canvas,
62
+ onBackground = XColors.TextPrimaryDark,
63
+ surface = XColors.Surface1,
64
+ onSurface = XColors.TextPrimaryDark,
65
+ surfaceVariant = XColors.Surface2,
66
+ outline = XColors.Divider,
67
+ error = XColors.ErrorRed,
68
+ )
69
+
70
+ private val XLight = lightColorScheme(
71
+ primary = XColors.Blue,
72
+ onPrimary = XColors.LightCanvas,
73
+ background = XColors.LightCanvas,
74
+ onBackground = XColors.TextPrimaryLight,
75
+ surface = XColors.LightSurface1,
76
+ onSurface = XColors.TextPrimaryLight,
77
+ surfaceVariant = XColors.LightSurface2,
78
+ outline = XColors.LightSurface2,
79
+ error = XColors.ErrorRed,
80
+ )
81
+
82
+ @Composable
83
+ fun XTheme(
84
+ darkTheme: Boolean = isSystemInDarkTheme(), // default-dark; expose dim as a third option in-app
85
+ content: @Composable () -> Unit,
86
+ ) = MaterialTheme(
87
+ colorScheme = if (darkTheme) XDark else XLight,
88
+ typography = XTypography,
89
+ content = content,
90
+ )
91
+ ```
92
+
93
+ ## 2. Typography
94
+
95
+ X licenses **Chirp** (Swiss Typefaces & Grilli Type, 2021) — a grotesque sans shipped in UI and Display optical sizes. Drop the TTFs in `res/font/` (lowercase, snake_case) and build a `FontFamily`. Fall back to **Roboto** (`FontFamily.Default`) — the closest grotesque on Android. The app switches optical size at the 17sp threshold; model it with two families.
96
+
97
+ ```kotlin
98
+ // ui/theme/XType.kt
99
+ import androidx.compose.material3.Typography
100
+ import androidx.compose.ui.text.TextStyle
101
+ import androidx.compose.ui.text.font.Font
102
+ import androidx.compose.ui.text.font.FontFamily
103
+ import androidx.compose.ui.text.font.FontWeight
104
+ import androidx.compose.ui.unit.sp
105
+
106
+ val ChirpUI = FontFamily(
107
+ Font(R.font.chirp_regular, FontWeight.Normal), // 400
108
+ Font(R.font.chirp_medium, FontWeight.Medium), // 500
109
+ Font(R.font.chirp_bold, FontWeight.Bold), // 700
110
+ )
111
+ val ChirpDisplay = FontFamily( // more open — used at 17sp+
112
+ Font(R.font.chirp_display_bold, FontWeight.Bold),
113
+ Font(R.font.chirp_regular, FontWeight.Normal),
114
+ )
115
+
116
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1)
117
+ object XText {
118
+ val ScreenTitle = TextStyle(ChirpDisplay, fontWeight = FontWeight.Bold, fontSize = 20.sp, lineHeight = 24.sp, letterSpacing = (-0.2).sp)
119
+ val SectionHeader = TextStyle(ChirpDisplay, fontWeight = FontWeight.Bold, fontSize = 17.sp, lineHeight = 21.sp, letterSpacing = (-0.1).sp)
120
+ val DisplayName = TextStyle(ChirpDisplay, fontWeight = FontWeight.Bold, fontSize = 15.sp, lineHeight = 20.sp)
121
+ val PostBody = TextStyle(ChirpUI, fontWeight = FontWeight.Normal, fontSize = 15.sp, lineHeight = 20.sp)
122
+ val QuotedBody = TextStyle(ChirpUI, fontWeight = FontWeight.Normal, fontSize = 14.sp, lineHeight = 18.sp)
123
+ val Handle = TextStyle(ChirpUI, fontWeight = FontWeight.Normal, fontSize = 15.sp, lineHeight = 20.sp)
124
+ val ActionCount = TextStyle(ChirpUI, fontWeight = FontWeight.Normal, fontSize = 13.sp, lineHeight = 16.sp)
125
+ val TrendingTopic = TextStyle(ChirpDisplay, fontWeight = FontWeight.Bold, fontSize = 15.sp, lineHeight = 19.sp)
126
+ val TrendingMeta = TextStyle(ChirpUI, fontWeight = FontWeight.Normal, fontSize = 13.sp, lineHeight = 16.sp)
127
+ val Button = TextStyle(ChirpUI, fontWeight = FontWeight.Bold, fontSize = 15.sp, lineHeight = 15.sp)
128
+ val DMBody = TextStyle(ChirpUI, fontWeight = FontWeight.Normal, fontSize = 15.sp, lineHeight = 19.sp)
129
+ val DMTimestamp = TextStyle(ChirpUI, fontWeight = FontWeight.Normal, fontSize = 11.sp, lineHeight = 13.sp)
130
+ }
131
+
132
+ // Map onto Material 3 slots so stock components inherit the ramp
133
+ val XTypography = Typography(
134
+ headlineLarge = XText.ScreenTitle,
135
+ titleLarge = XText.SectionHeader,
136
+ titleMedium = XText.DisplayName,
137
+ bodyLarge = XText.PostBody,
138
+ bodyMedium = XText.QuotedBody,
139
+ labelLarge = XText.Button,
140
+ )
141
+ ```
142
+
143
+ ## 3. Signature Components
144
+
145
+ ### Post Row (hairline-separated, column-centered feed)
146
+
147
+ The feed is a flat river of full-bleed posts joined by 1dp `Divider`s — never cards, never shadows. Post content begins at a 68dp leading indent (16dp margin + 32dp avatar + 12dp gutter) and the action row aligns to that same indent.
148
+
149
+ ```kotlin
150
+ import androidx.compose.foundation.background
151
+ import androidx.compose.foundation.clickable
152
+ import androidx.compose.foundation.layout.*
153
+ import androidx.compose.foundation.shape.CircleShape
154
+ import androidx.compose.material.icons.Icons
155
+ import androidx.compose.material.icons.filled.MoreHoriz
156
+ import androidx.compose.material.icons.filled.Verified
157
+ import androidx.compose.material3.HorizontalDivider
158
+ import androidx.compose.material3.Icon
159
+ import androidx.compose.material3.Text
160
+ import androidx.compose.runtime.*
161
+ import androidx.compose.ui.Alignment
162
+ import androidx.compose.ui.Modifier
163
+ import androidx.compose.ui.draw.clip
164
+ import androidx.compose.ui.text.style.TextOverflow
165
+ import androidx.compose.ui.unit.dp
166
+ import coil.compose.AsyncImage
167
+
168
+ @Composable
169
+ fun XPostRow(
170
+ avatarUrl: String,
171
+ displayName: String,
172
+ handle: String,
173
+ timestamp: String,
174
+ isVerified: Boolean,
175
+ body: String,
176
+ replyCount: Int,
177
+ repostCount: Int,
178
+ likeCount: Int,
179
+ viewCount: Int,
180
+ onClick: () -> Unit,
181
+ modifier: Modifier = Modifier,
182
+ ) {
183
+ var isLiked by remember { mutableStateOf(false) }
184
+ var isReposted by remember { mutableStateOf(false) }
185
+ var isBookmarked by remember { mutableStateOf(false) }
186
+
187
+ Column(
188
+ modifier
189
+ .fillMaxWidth()
190
+ .background(XColors.Canvas)
191
+ .clickable(onClick = onClick)
192
+ ) {
193
+ Row(
194
+ Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
195
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
196
+ ) {
197
+ AsyncImage(
198
+ model = avatarUrl,
199
+ contentDescription = "$displayName avatar",
200
+ modifier = Modifier.size(32.dp).clip(CircleShape),
201
+ )
202
+ Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(4.dp)) {
203
+ Row(verticalAlignment = Alignment.CenterVertically) {
204
+ Text(displayName, style = XText.DisplayName, color = XColors.TextPrimaryDark, maxLines = 1)
205
+ if (isVerified) {
206
+ Spacer(Modifier.width(2.dp))
207
+ Icon(Icons.Filled.Verified, contentDescription = "Verified", tint = XColors.Blue, modifier = Modifier.size(16.dp))
208
+ }
209
+ Spacer(Modifier.width(4.dp))
210
+ Text(
211
+ "@$handle · $timestamp",
212
+ style = XText.Handle,
213
+ color = XColors.TextSecondaryDark,
214
+ maxLines = 1,
215
+ overflow = TextOverflow.Ellipsis,
216
+ modifier = Modifier.weight(1f, fill = false),
217
+ )
218
+ Spacer(Modifier.weight(1f))
219
+ Icon(Icons.Filled.MoreHoriz, contentDescription = "More", tint = XColors.TextSecondaryDark, modifier = Modifier.size(18.dp))
220
+ }
221
+ Text(body, style = XText.PostBody, color = XColors.TextPrimaryDark)
222
+ Row(
223
+ Modifier.fillMaxWidth().padding(top = 8.dp),
224
+ horizontalArrangement = Arrangement.SpaceBetween,
225
+ ) {
226
+ XActionIcon(ActionType.Reply, replyCount, active = false) { /* open composer */ }
227
+ XActionIcon(ActionType.Repost, repostCount, active = isReposted) { isReposted = !isReposted }
228
+ XActionIcon(ActionType.Like, likeCount, active = isLiked) { isLiked = !isLiked }
229
+ XActionIcon(ActionType.Views, viewCount, active = false) {}
230
+ XActionIcon(ActionType.Bookmark, 0, active = isBookmarked) { isBookmarked = !isBookmarked }
231
+ }
232
+ }
233
+ }
234
+ HorizontalDivider(thickness = 1.dp, color = XColors.Divider)
235
+ }
236
+ }
237
+ ```
238
+
239
+ ### Action Icon (per-action color micro-animation — see §4)
240
+
241
+ ```kotlin
242
+ import androidx.compose.material.icons.filled.BarChart
243
+ import androidx.compose.material.icons.filled.Bookmark
244
+ import androidx.compose.material.icons.filled.Favorite
245
+ import androidx.compose.material.icons.filled.Repeat
246
+ import androidx.compose.material.icons.outlined.BookmarkBorder
247
+ import androidx.compose.material.icons.outlined.ChatBubbleOutline
248
+ import androidx.compose.material.icons.outlined.FavoriteBorder
249
+
250
+ enum class ActionType { Reply, Repost, Like, Views, Bookmark }
251
+
252
+ @Composable
253
+ fun XActionIcon(
254
+ type: ActionType,
255
+ count: Int,
256
+ active: Boolean,
257
+ onClick: () -> Unit,
258
+ ) {
259
+ val activeColor = when (type) {
260
+ ActionType.Reply, ActionType.Bookmark -> XColors.Blue
261
+ ActionType.Repost -> XColors.RepostGreen
262
+ ActionType.Like -> XColors.LikePink
263
+ ActionType.Views -> XColors.TextSecondaryDark
264
+ }
265
+ val tint = if (active) activeColor else XColors.TextSecondaryDark
266
+ val icon = when (type) {
267
+ ActionType.Reply -> Icons.Outlined.ChatBubbleOutline
268
+ ActionType.Repost -> Icons.Filled.Repeat
269
+ ActionType.Like -> if (active) Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder
270
+ ActionType.Views -> Icons.Filled.BarChart
271
+ ActionType.Bookmark -> if (active) Icons.Filled.Bookmark else Icons.Outlined.BookmarkBorder
272
+ }
273
+ Row(
274
+ Modifier
275
+ .sizeIn(minWidth = 44.dp, minHeight = 44.dp)
276
+ .clickable(onClick = onClick),
277
+ verticalAlignment = Alignment.CenterVertically,
278
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
279
+ ) {
280
+ Icon(icon, contentDescription = type.name, tint = tint, modifier = Modifier.size(18.75.dp))
281
+ if (count > 0) Text(formatCount(count), style = XText.ActionCount, color = tint)
282
+ }
283
+ }
284
+
285
+ fun formatCount(n: Int): String = when {
286
+ n >= 1_000_000 -> "%.1fM".format(n / 1_000_000f)
287
+ n >= 1_000 -> "%.1fK".format(n / 1_000f)
288
+ else -> "$n"
289
+ }
290
+ ```
291
+
292
+ ### Floating Post Button (inverted FAB)
293
+
294
+ ```kotlin
295
+ import androidx.compose.animation.core.animateFloatAsState
296
+ import androidx.compose.animation.core.spring
297
+ import androidx.compose.foundation.interaction.MutableInteractionSource
298
+ import androidx.compose.foundation.interaction.collectIsPressedAsState
299
+ import androidx.compose.material.icons.filled.Create
300
+ import androidx.compose.ui.draw.scale
301
+ import androidx.compose.ui.draw.shadow
302
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
303
+ import androidx.compose.ui.platform.LocalHapticFeedback
304
+
305
+ @Composable
306
+ fun XPostFab(onClick: () -> Unit, modifier: Modifier = Modifier, darkTheme: Boolean = true) {
307
+ val interaction = remember { MutableInteractionSource() }
308
+ val pressed by interaction.collectIsPressedAsState()
309
+ val scale by animateFloatAsState(if (pressed) 0.95f else 1f, label = "fabScale")
310
+ val haptics = LocalHapticFeedback.current
311
+ // Inverted from canvas: white-on-black (dark) / black-on-white (light)
312
+ val bg = if (darkTheme) XColors.LightCanvas else XColors.TextPrimaryLight
313
+ val fg = if (darkTheme) XColors.Canvas else XColors.LightCanvas
314
+
315
+ Box(
316
+ modifier = modifier
317
+ .padding(end = 16.dp, bottom = 16.dp)
318
+ .size(56.dp)
319
+ .scale(scale)
320
+ .shadow(12.dp, CircleShape, ambientColor = Color.Black.copy(alpha = 0.4f))
321
+ .clip(CircleShape)
322
+ .background(bg)
323
+ .clickable(interaction, indication = null) {
324
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress)
325
+ onClick()
326
+ },
327
+ contentAlignment = Alignment.Center,
328
+ ) {
329
+ Icon(Icons.Filled.Create, contentDescription = "Compose post", tint = fg, modifier = Modifier.size(24.dp))
330
+ }
331
+ }
332
+ ```
333
+
334
+ ### Follow Pill
335
+
336
+ ```kotlin
337
+ import androidx.compose.foundation.border
338
+
339
+ @Composable
340
+ fun XFollowPill(isFollowing: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) {
341
+ Box(
342
+ modifier = modifier
343
+ .widthIn(min = 80.dp)
344
+ .clip(CircleShape)
345
+ .then(
346
+ if (isFollowing) Modifier.border(1.dp, XColors.TextSecondaryDark, CircleShape)
347
+ else Modifier.background(XColors.TextPrimaryDark)
348
+ )
349
+ .clickable(onClick = onClick)
350
+ .padding(horizontal = 16.dp, vertical = 8.dp),
351
+ contentAlignment = Alignment.Center,
352
+ ) {
353
+ Text(
354
+ if (isFollowing) "Following" else "Follow", // sentence case — never uppercase
355
+ style = XText.Button,
356
+ color = if (isFollowing) XColors.TextPrimaryDark else XColors.Canvas,
357
+ )
358
+ }
359
+ }
360
+ ```
361
+
362
+ ## 4. Per-Action Color Micro-Animations + Column-Centered Feed
363
+
364
+ X's most recognizable micro-interaction: each action icon scale-bounces, snaps to its role color, the count ticks up, and a `.impact(.light)` haptic fires. Like adds a 6-particle hexagonal burst; repost spins the glyph 360°.
365
+
366
+ ```kotlin
367
+ import androidx.compose.animation.AnimatedContent
368
+ import androidx.compose.animation.core.Animatable
369
+ import androidx.compose.animation.core.tween
370
+ import androidx.compose.animation.slideInVertically
371
+ import androidx.compose.animation.slideOutVertically
372
+ import androidx.compose.animation.fadeIn
373
+ import androidx.compose.animation.fadeOut
374
+ import androidx.compose.animation.togetherWith
375
+ import androidx.compose.ui.graphics.graphicsLayer
376
+ import kotlin.math.cos
377
+ import kotlin.math.sin
378
+
379
+ /** Like icon: scale 0.85 → 1.2 → 1, 6-particle hexagonal burst, count tick-up, light haptic. */
380
+ @Composable
381
+ fun XLikeButton(initialCount: Int) {
382
+ var liked by remember { mutableStateOf(false) }
383
+ var count by remember { mutableIntStateOf(initialCount) }
384
+ val scale = remember { Animatable(1f) }
385
+ val burst = remember { Animatable(0f) }
386
+ val haptics = LocalHapticFeedback.current
387
+
388
+ LaunchedEffect(liked) {
389
+ if (liked) {
390
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove) // ~iOS .impact(.light)
391
+ scale.snapTo(0.85f)
392
+ burst.snapTo(0f)
393
+ kotlinx.coroutines.coroutineScope {
394
+ launch { scale.animateTo(1.2f, spring(dampingRatio = 0.55f, stiffness = 600f)); scale.animateTo(1f) }
395
+ launch { burst.animateTo(1f, tween(400)) }
396
+ }
397
+ }
398
+ }
399
+
400
+ Row(
401
+ Modifier
402
+ .sizeIn(minWidth = 44.dp, minHeight = 44.dp)
403
+ .clickable { liked = !liked; count += if (liked) 1 else -1 },
404
+ verticalAlignment = Alignment.CenterVertically,
405
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
406
+ ) {
407
+ Box(contentAlignment = Alignment.Center) {
408
+ // Hexagonal particle burst
409
+ if (burst.value > 0f && burst.value < 1f) {
410
+ repeat(6) { i ->
411
+ val angle = i * Math.PI / 3
412
+ Box(
413
+ Modifier
414
+ .size(4.dp)
415
+ .graphicsLayer {
416
+ translationX = (cos(angle) * 18 * burst.value).toFloat() * density
417
+ translationY = (sin(angle) * 18 * burst.value).toFloat() * density
418
+ alpha = 1f - burst.value
419
+ }
420
+ .clip(CircleShape)
421
+ .background(XColors.LikePink)
422
+ )
423
+ }
424
+ }
425
+ Icon(
426
+ imageVector = if (liked) Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder,
427
+ contentDescription = "Like",
428
+ tint = if (liked) XColors.LikePink else XColors.TextSecondaryDark,
429
+ modifier = Modifier.size(18.75.dp).scale(scale.value),
430
+ )
431
+ }
432
+ // Count tick-up: old value slides up + fades, new value slides in from below
433
+ AnimatedContent(
434
+ targetState = count,
435
+ transitionSpec = {
436
+ (slideInVertically { it } + fadeIn()) togetherWith (slideOutVertically { -it } + fadeOut())
437
+ },
438
+ label = "likeCount",
439
+ ) { c ->
440
+ Text(formatCount(c), style = XText.ActionCount, color = if (liked) XColors.LikePink else XColors.TextSecondaryDark)
441
+ }
442
+ }
443
+ }
444
+
445
+ /** Repost icon spins 0 → 360° as it fills green. */
446
+ @Composable
447
+ fun XRepostButton(initialCount: Int) {
448
+ var reposted by remember { mutableStateOf(false) }
449
+ val rotation = remember { Animatable(0f) }
450
+ val haptics = LocalHapticFeedback.current
451
+ LaunchedEffect(reposted) {
452
+ if (reposted) {
453
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove)
454
+ rotation.animateTo(rotation.value + 360f, tween(400))
455
+ }
456
+ }
457
+ Icon(
458
+ Icons.Filled.Repeat,
459
+ contentDescription = "Repost",
460
+ tint = if (reposted) XColors.RepostGreen else XColors.TextSecondaryDark,
461
+ modifier = Modifier
462
+ .size(18.75.dp)
463
+ .graphicsLayer { rotationZ = rotation.value }
464
+ .clickable { reposted = !reposted },
465
+ )
466
+ }
467
+ ```
468
+
469
+ The **column-centered feed** is a single `LazyColumn` of `XPostRow`s separated only by their built-in `HorizontalDivider` — set `verticalArrangement = Arrangement.spacedBy(0.dp)` (posts touch; the hairline is the only separator). On wide breakpoints (`> 840.dp`), constrain the feed column to a max width and center it, mirroring iPad split view.
470
+
471
+ ## 5. Bottom Navigation (Tab Bar)
472
+
473
+ Use Material 3 `NavigationBar`, **icon-only with no labels** — X's signature pattern. The iOS bar is `.regularMaterial` blur at ~85% over canvas; Android has no first-class live blur, so use an 85%-opaque canvas surface. **Active tint is the stark off-white `#E7E9EA` (not blue)**; active icons are filled, inactive outlined.
474
+
475
+ ```kotlin
476
+ import androidx.compose.material.icons.filled.Home
477
+ import androidx.compose.material.icons.filled.Mail
478
+ import androidx.compose.material.icons.filled.Notifications
479
+ import androidx.compose.material.icons.filled.People
480
+ import androidx.compose.material.icons.filled.Search
481
+ import androidx.compose.material.icons.outlined.HomeOutlined
482
+ import androidx.compose.material.icons.outlined.MailOutline
483
+ import androidx.compose.material.icons.outlined.NotificationsNone
484
+ import androidx.compose.material.icons.outlined.PeopleOutline
485
+ import androidx.compose.material3.NavigationBar
486
+ import androidx.compose.material3.NavigationBarItem
487
+ import androidx.compose.material3.NavigationBarItemDefaults
488
+
489
+ @Composable
490
+ fun XBottomBar(selected: Int, onSelect: (Int) -> Unit) {
491
+ NavigationBar(
492
+ containerColor = XColors.Canvas.copy(alpha = 0.85f),
493
+ tonalElevation = 0.dp,
494
+ ) {
495
+ data class Tab(val filled: androidx.compose.ui.graphics.vector.ImageVector, val outlined: androidx.compose.ui.graphics.vector.ImageVector, val cd: String)
496
+ val tabs = listOf(
497
+ Tab(Icons.Filled.Home, Icons.Outlined.HomeOutlined, "Home"),
498
+ Tab(Icons.Filled.Search, Icons.Filled.Search, "Search"),
499
+ Tab(Icons.Filled.People, Icons.Outlined.PeopleOutline, "Communities"),
500
+ Tab(Icons.Filled.Notifications, Icons.Outlined.NotificationsNone, "Notifications"),
501
+ Tab(Icons.Filled.Mail, Icons.Outlined.MailOutline, "Messages"),
502
+ )
503
+ tabs.forEachIndexed { i, tab ->
504
+ val isSel = selected == i
505
+ NavigationBarItem(
506
+ selected = isSel,
507
+ onClick = { onSelect(i) },
508
+ icon = {
509
+ Icon(
510
+ if (isSel) tab.filled else tab.outlined,
511
+ contentDescription = tab.cd,
512
+ modifier = Modifier.size(26.dp),
513
+ )
514
+ },
515
+ label = null, // icon-only — X's signature
516
+ colors = NavigationBarItemDefaults.colors(
517
+ selectedIconColor = XColors.TextPrimaryDark, // off-white, NOT blue
518
+ unselectedIconColor = XColors.TextSecondaryDark,
519
+ indicatorColor = Color.Transparent, // no Material pill — X has none
520
+ ),
521
+ )
522
+ }
523
+ }
524
+ }
525
+ ```
526
+
527
+ The **feed filter** ("For you" / "Following") sits below the top nav: two Chirp 15sp/700 labels; the active one gets a 40dp × 4dp `#1D9BF0` pill underline that slides between positions via an `animateDpAsState` offset (the Compose analog to `matchedGeometryEffect`).
528
+
529
+ ## 6. Motion
530
+
531
+ | Moment | Compose recipe |
532
+ |--------|----------------|
533
+ | Like tap | `Animatable` scale 0.85 → 1.2 → 1 `spring(dampingRatio = 0.55f)`; 6-particle `graphicsLayer` burst over 400ms; `AnimatedContent` count tick-up; `HapticFeedbackType.TextHandleMove` |
534
+ | Repost tap | `Animatable` `rotationZ` += 360 over 400ms `tween` as tint → green; light haptic |
535
+ | Reply tap | icon scale 0.9 → 1.05 → 1 `spring`; navigate to compose (`slideInVertically`) |
536
+ | Feed swipe For You ↔ Following | `HorizontalPager` 280ms spring; underline `animateDpAsState` offset (≈ `matchedGeometryEffect`) |
537
+ | Pull-to-refresh | custom: a line that expands into the X glyph as overscroll grows, then spins |
538
+ | Tab switch | instant `Crossfade` (no slide) |
539
+ | Compose open | `ModalBottomSheet` / full-screen route `slideInVertically` 320ms spring + scrim fade |
540
+
541
+ ```kotlin
542
+ // Feed filter underline — Android's analog to iOS .matchedGeometryEffect
543
+ import androidx.compose.animation.core.animateDpAsState
544
+ import androidx.compose.foundation.layout.offset
545
+
546
+ @Composable
547
+ fun XFeedFilter(selected: Int, onSelect: (Int) -> Unit) {
548
+ val labels = listOf("For you", "Following")
549
+ BoxWithConstraints(Modifier.fillMaxWidth().height(48.dp)) {
550
+ val tabWidth = maxWidth / 2
551
+ val indicatorX by animateDpAsState(
552
+ targetValue = tabWidth * selected + (tabWidth - 40.dp) / 2,
553
+ animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f),
554
+ label = "filterUnderline",
555
+ )
556
+ Row(Modifier.fillMaxSize()) {
557
+ labels.forEachIndexed { i, label ->
558
+ Box(
559
+ Modifier.weight(1f).fillMaxHeight().clickable { onSelect(i) },
560
+ contentAlignment = Alignment.Center,
561
+ ) {
562
+ Text(
563
+ label,
564
+ style = XText.Button,
565
+ color = if (selected == i) XColors.TextPrimaryDark else XColors.TextSecondaryDark,
566
+ )
567
+ }
568
+ }
569
+ }
570
+ Box(
571
+ Modifier
572
+ .offset(x = indicatorX)
573
+ .align(Alignment.BottomStart)
574
+ .width(40.dp)
575
+ .height(4.dp)
576
+ .clip(CircleShape)
577
+ .background(XColors.Blue)
578
+ )
579
+ HorizontalDivider(Modifier.align(Alignment.BottomCenter), thickness = 1.dp, color = XColors.Divider)
580
+ }
581
+ }
582
+ ```
583
+
584
+ Haptics: prefer `LocalHapticFeedback`. `HapticFeedbackType.TextHandleMove` is the lightest stock effect ≈ iOS `.impact(.light)` for every action tap. For richer control use `LocalView.current.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)` (API 30+) or a `Vibrator` `VibrationEffect.createOneShot(8, 60)`.
585
+
586
+ ## 7. Icons
587
+
588
+ X ships custom monochrome glyphs (the X logo most notably); the closest first-party set is `androidx.compose.material:material-icons-extended`. The X logotype, the precise Chirp-styled action glyphs, and the Grok sparkle should ship as vector drawables loaded via `ImageVector.vectorResource(R.drawable.…)` — the X logo is **monochrome, never tinted**.
589
+
590
+ | Purpose | SF Symbol (iOS) | Material Icon (Compose) |
591
+ |---------|-----------------|--------------------------|
592
+ | Reply | `bubble.left` | `Icons.Outlined.ChatBubbleOutline` |
593
+ | Repost | `arrow.2.squarepath` | `Icons.Filled.Repeat` |
594
+ | Like (outline / fill) | `heart` / `heart.fill` | `Icons.Outlined.FavoriteBorder` / `Icons.Filled.Favorite` |
595
+ | Views | `chart.bar` | `Icons.Filled.BarChart` |
596
+ | Bookmark (outline / fill) | `bookmark` / `bookmark.fill` | `Icons.Outlined.BookmarkBorder` / `Icons.Filled.Bookmark` |
597
+ | Share | `square.and.arrow.up` | `Icons.Filled.IosShare` |
598
+ | Verified | `checkmark.seal.fill` | `Icons.Filled.Verified` |
599
+ | Overflow | `ellipsis` | `Icons.Filled.MoreHoriz` |
600
+ | Compose (FAB) | `pencil.and.outline` | `Icons.Filled.Create` |
601
+ | Home tab | `house.fill` | `Icons.Filled.Home` / `Icons.Outlined.HomeOutlined` |
602
+ | Search tab | `magnifyingglass` | `Icons.Filled.Search` |
603
+ | Communities tab | `person.3.fill` | `Icons.Filled.People` / `Icons.Outlined.PeopleOutline` |
604
+ | Notifications tab | `bell.fill` | `Icons.Filled.Notifications` / `Icons.Outlined.NotificationsNone` |
605
+ | Messages tab | `envelope.fill` | `Icons.Filled.Mail` / `Icons.Outlined.MailOutline` |
606
+ | Grok | `sparkles` | `Icons.Filled.AutoAwesome` (or vector drawable) |
607
+ | X logo | (custom glyph) | vector drawable — monochrome, never tinted |
608
+
609
+ ## 8. Minimum SDK & Accessibility Notes
610
+
611
+ - **minSdk 24** (Compose floor is 21; `AnimatedContent`, `graphicsLayer` bursts, and `HorizontalPager` are comfortable at 24). `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`.
612
+ - **Edge-to-edge**: call `enableEdgeToEdge()` in the `Activity` with light-content system bars (the canvas is true black). The FAB floats 16.dp above the bottom bar; apply `Scaffold` insets so both clear the gesture nav, and let the top nav draw under the status bar with its translucent surface.
613
+ - **Font scaling**: `sp` honors the user's font scale — keep it on post body, quoted body, and DM body. **Pin** display name, handle, timestamp, and the 13sp action counts (layout-critical for the post-row header and action row) by deriving them from a fixed-`fontScale` `LocalDensity`.
614
+ - **TalkBack**: merge each post into a single node with `Modifier.semantics(mergeDescendants = true)` and a readable label; expose action icons as separate buttons with state-aware descriptions (`"Like post, 1.2 thousand likes"` / `"Liked"`). The avatar and overflow are independent buttons.
615
+ - **Touch targets**: Material guidance is 48.dp minimum. Action glyphs render at 18.75.dp — each is already wrapped in a `sizeIn(minWidth = 44.dp, minHeight = 44.dp)` row; bump to 48.dp if targeting strict compliance. The 32dp avatar and 20dp overflow need a 44–48dp hit area via padding.
616
+ - **Reduce Motion**: respect the system "remove animations" setting — skip the like-burst particles and the repost spin, but keep the color change, the count update, and the haptic so the action still confirms.
617
+ - **Contrast**: off-white `#E7E9EA` on `#000000` exceeds WCAG AA. `#71767B` secondary on true black is borderline at small sizes — keep handles/timestamps at 15sp and action counts at 13sp minimum; do not dim secondary text further. Like-pink `#F91880` and repost-green `#00BA7C` on black pass AA for the icon/count sizes used.
618
+ - **Dynamic color**: do **not** enable Material You `dynamicColorScheme()` — X's identity is the fixed true-black canvas, the structural blue, and the three 1:1 action colors regardless of wallpaper. Keep the hand-built dark/light schemes (and offer dim as an explicit in-app third theme).