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,635 @@
1
+ # WHOOP (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports WHOOP's instrument-panel aesthetic to **Android with Jetpack Compose (Material 3)**: a color token object, a `Typography` set, the Recovery ring with red→yellow→green interpolation, the strain bar, the sleep stage chart, neon glows, 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 (WHOOP's pitch-black cockpit canvas, neon Strain Green, the score-driven Recovery ramp, tabular DIN numerals, neon-glow elevation) while making everything idiomatic Android — `NavigationBar` instead of a UITabBar, `drawArc`/`Canvas` instead of SwiftUI `Path`, a translucent `Surface` instead of `.systemThinMaterialDark`, `sp`/`dp` instead of `pt`. WHOOP is dark-canvas-only by design — there is no light scheme.
6
+
7
+ Assumes Compose BOM `2024.09+`, Kotlin `2.0+`, `minSdk 24`, Material 3. No remote-image or color-extraction libraries are needed — WHOOP's palette is fixed brand chrome and the Recovery color is computed, not extracted.
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/WhoopColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+ import androidx.compose.ui.graphics.lerp
15
+
16
+ object WhoopColors {
17
+ // Canvas & surfaces (dark-only)
18
+ val Canvas = Color(0xFF0A0A0A)
19
+ val Surface1 = Color(0xFF1C1C1E)
20
+ val Surface2 = Color(0xFF2A2A2A)
21
+ val Surface3 = Color(0xFF3A3A3A)
22
+ val Divider = Color(0xFF252525)
23
+ val Hairline = Color(0xFF1A1A1A)
24
+
25
+ // Strain (primary brand)
26
+ val Strain = Color(0xFF00FF7B)
27
+ val StrainBright = Color(0xFF67E26B)
28
+ val StrainDim = Color(0xFF005F2F)
29
+
30
+ // Recovery spectrum
31
+ val RecoveryRed = Color(0xFFFF0026)
32
+ val RecoveryYellow = Color(0xFFFFDE00)
33
+ val RecoveryGreen = Color(0xFF16EC06)
34
+
35
+ // Sleep
36
+ val SleepBlue = Color(0xFF0093E7)
37
+ val SleepBlueBright = Color(0xFF4FB8FF)
38
+ val REMPurple = Color(0xFF9C4DFF)
39
+ val DeepIndigo = Color(0xFF3D3DFF)
40
+ val LightCyan = Color(0xFF3DD9FF)
41
+
42
+ // Text
43
+ val BrightWhite = Color(0xFFFFFFFF)
44
+ val SoftWhite = Color(0xFFF5F5F7)
45
+ val Gray400 = Color(0xFFA1A1AA)
46
+ val Gray600 = Color(0xFF5F5F65)
47
+ val Gray700 = Color(0xFF3F3F45)
48
+
49
+ // Semantic
50
+ val AlertRed = Color(0xFFFF453A)
51
+ val WarningAmber = Color(0xFFFFAA00)
52
+ val InfoBlue = Color(0xFF0A84FF)
53
+ val Success = Color(0xFF30D158)
54
+ val PremiumGold = Color(0xFFD4AF37)
55
+
56
+ /** Recovery ring color for a score 0..100, lerped red→yellow→green. */
57
+ fun recoveryColor(percent: Float): Color {
58
+ val p = percent.coerceIn(0f, 100f) / 100f
59
+ return when {
60
+ p < 0.33f -> RecoveryRed
61
+ p < 0.67f -> lerp(RecoveryRed, RecoveryYellow, (p - 0.33f) / 0.34f)
62
+ else -> lerp(RecoveryYellow, RecoveryGreen, (p - 0.67f) / 0.33f)
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ WHOOP has **no light mode**. Provide a single `darkColorScheme` — the dark canvas and neon Strain Green are inseparable from the brand.
69
+
70
+ ```kotlin
71
+ // ui/theme/Theme.kt
72
+ import androidx.compose.material3.darkColorScheme
73
+ import androidx.compose.material3.MaterialTheme
74
+ import androidx.compose.runtime.Composable
75
+
76
+ private val WhoopScheme = darkColorScheme(
77
+ primary = WhoopColors.Strain,
78
+ onPrimary = WhoopColors.Canvas, // intentional: black on neon green
79
+ background = WhoopColors.Canvas,
80
+ onBackground = WhoopColors.SoftWhite,
81
+ surface = WhoopColors.Surface1,
82
+ onSurface = WhoopColors.SoftWhite,
83
+ surfaceVariant = WhoopColors.Surface2,
84
+ outline = WhoopColors.Divider,
85
+ error = WhoopColors.AlertRed,
86
+ )
87
+
88
+ @Composable
89
+ fun WhoopTheme(content: @Composable () -> Unit) =
90
+ MaterialTheme(colorScheme = WhoopScheme, typography = WhoopTypography, content = content)
91
+ ```
92
+
93
+ ## 2. Typography
94
+
95
+ WHOOP licenses **DIN 2014**. Drop the TTFs in `res/font/` (lowercase, snake_case) and build a `FontFamily`. Fall back to a tabular sans — bundle Inter (`res/font/inter_*`), the only acceptable substitute because it shares DIN's mechanical, slightly condensed proportions and ships tabular figures.
96
+
97
+ ```kotlin
98
+ // ui/theme/WhoopType.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.text.style.TextGeometricTransform
105
+ import androidx.compose.ui.unit.sp
106
+
107
+ val Din2014 = FontFamily(
108
+ Font(R.font.din2014_regular, FontWeight.Normal), // 400
109
+ Font(R.font.din2014_demi, FontWeight.Medium), // 500
110
+ Font(R.font.din2014_bold, FontWeight.Bold), // 700
111
+ Font(R.font.din2014_extrabold, FontWeight.ExtraBold), // 800
112
+ // Fallback chain: Inter ships tabular figures with similar proportions
113
+ Font(R.font.inter_regular, FontWeight.Normal),
114
+ Font(R.font.inter_bold, FontWeight.Bold),
115
+ )
116
+
117
+ // Tabular figures are non-negotiable — apply to every metric value.
118
+ import androidx.compose.ui.text.font.FontFeatureSetting
119
+ private const val TNUM = "tnum"
120
+
121
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1).
122
+ object WhoopText {
123
+ val RecoveryHero = TextStyle(Din2014, fontWeight = FontWeight.ExtraBold, fontSize = 76.sp, lineHeight = 76.sp, letterSpacing = (-1.6).sp, fontFeatureSettings = TNUM)
124
+ val StrainHero = TextStyle(Din2014, fontWeight = FontWeight.ExtraBold, fontSize = 56.sp, lineHeight = 56.sp, letterSpacing = (-1.0).sp, fontFeatureSettings = TNUM)
125
+ val SleepHero = TextStyle(Din2014, fontWeight = FontWeight.ExtraBold, fontSize = 48.sp, lineHeight = 48.sp, letterSpacing = (-0.8).sp, fontFeatureSettings = TNUM)
126
+ val SectionCaps = TextStyle(Din2014, fontWeight = FontWeight.Bold, fontSize = 14.sp, lineHeight = 14.sp, letterSpacing = 1.6.sp) // UPPERCASE
127
+ val LargeNav = TextStyle(Din2014, fontWeight = FontWeight.Bold, fontSize = 24.sp, lineHeight = 28.sp, letterSpacing = (-0.2).sp)
128
+ val Subhead = TextStyle(Din2014, fontWeight = FontWeight.Bold, fontSize = 18.sp, lineHeight = 22.sp)
129
+ val CardTitle = TextStyle(Din2014, fontWeight = FontWeight.Medium, fontSize = 15.sp, lineHeight = 19.sp, letterSpacing = (-0.05).sp)
130
+ val Body = TextStyle(Din2014, fontWeight = FontWeight.Normal, fontSize = 14.sp, lineHeight = 20.sp)
131
+ val MetaCaps = TextStyle(Din2014, fontWeight = FontWeight.Bold, fontSize = 11.sp, lineHeight = 11.sp, letterSpacing = 1.2.sp) // UPPERCASE
132
+ val MetricValue = TextStyle(Din2014, fontWeight = FontWeight.Bold, fontSize = 18.sp, lineHeight = 18.sp, fontFeatureSettings = TNUM)
133
+ val MetricLabel = TextStyle(Din2014, fontWeight = FontWeight.Medium, fontSize = 11.sp, lineHeight = 11.sp, letterSpacing = 0.6.sp) // UPPERCASE
134
+ val Button = TextStyle(Din2014, fontWeight = FontWeight.Bold, fontSize = 14.sp, lineHeight = 14.sp, letterSpacing = 1.0.sp) // UPPERCASE
135
+ val Tab = TextStyle(Din2014, fontWeight = FontWeight.Bold, fontSize = 10.sp, lineHeight = 10.sp, letterSpacing = 0.8.sp) // UPPERCASE
136
+ val ChartAxis = TextStyle(Din2014, fontWeight = FontWeight.Medium, fontSize = 10.sp, lineHeight = 10.sp, letterSpacing = 0.2.sp, fontFeatureSettings = TNUM)
137
+ }
138
+
139
+ // Headers/labels are uppercased at the call site (text.uppercase()) — Compose has no text-transform.
140
+
141
+ val WhoopTypography = Typography(
142
+ displayLarge = WhoopText.RecoveryHero,
143
+ headlineLarge = WhoopText.LargeNav,
144
+ titleLarge = WhoopText.Subhead,
145
+ titleMedium = WhoopText.CardTitle,
146
+ bodyMedium = WhoopText.Body,
147
+ labelSmall = WhoopText.Tab,
148
+ )
149
+ ```
150
+
151
+ ## 3. Signature Components
152
+
153
+ ### Primary CTA (instrument-panel button — 4dp radius, never a pill)
154
+
155
+ ```kotlin
156
+ import androidx.compose.animation.core.animateFloatAsState
157
+ import androidx.compose.animation.core.spring
158
+ import androidx.compose.foundation.background
159
+ import androidx.compose.foundation.clickable
160
+ import androidx.compose.foundation.interaction.MutableInteractionSource
161
+ import androidx.compose.foundation.interaction.collectIsPressedAsState
162
+ import androidx.compose.foundation.layout.*
163
+ import androidx.compose.foundation.shape.RoundedCornerShape
164
+ import androidx.compose.material3.Text
165
+ import androidx.compose.runtime.*
166
+ import androidx.compose.ui.Alignment
167
+ import androidx.compose.ui.Modifier
168
+ import androidx.compose.ui.draw.clip
169
+ import androidx.compose.ui.draw.scale
170
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
171
+ import androidx.compose.ui.platform.LocalHapticFeedback
172
+ import androidx.compose.ui.unit.dp
173
+
174
+ @Composable
175
+ fun WhoopPrimaryButton(
176
+ label: String, // pass already-uppercase or call label.uppercase()
177
+ onClick: () -> Unit,
178
+ modifier: Modifier = Modifier,
179
+ ) {
180
+ val interaction = remember { MutableInteractionSource() }
181
+ val pressed by interaction.collectIsPressedAsState()
182
+ val scale by animateFloatAsState(if (pressed) 0.98f else 1f, label = "ctaScale")
183
+ val haptics = LocalHapticFeedback.current
184
+
185
+ Box(
186
+ modifier = modifier
187
+ .fillMaxWidth()
188
+ .heightIn(min = 48.dp)
189
+ .scale(scale)
190
+ .clip(RoundedCornerShape(4.dp)) // instrument-panel rectangle
191
+ .background(if (pressed) WhoopColors.StrainBright else WhoopColors.Strain)
192
+ .clickable(interaction, indication = null) {
193
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // ~iOS medium impact
194
+ onClick()
195
+ }
196
+ .padding(horizontal = 28.dp, vertical = 14.dp),
197
+ contentAlignment = Alignment.Center,
198
+ ) {
199
+ Text(label.uppercase(), style = WhoopText.Button, color = WhoopColors.Canvas)
200
+ }
201
+ }
202
+
203
+ @Composable
204
+ fun WhoopOutlineButton(label: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
205
+ Box(
206
+ modifier = modifier
207
+ .fillMaxWidth()
208
+ .heightIn(min = 48.dp)
209
+ .clip(RoundedCornerShape(4.dp))
210
+ .border(1.5.dp, WhoopColors.Strain, RoundedCornerShape(4.dp))
211
+ .clickable(onClick = onClick)
212
+ .padding(horizontal = 28.dp, vertical = 14.dp),
213
+ contentAlignment = Alignment.Center,
214
+ ) {
215
+ Text(label.uppercase(), style = WhoopText.Button, color = WhoopColors.Strain)
216
+ }
217
+ }
218
+ ```
219
+
220
+ ### Strain Bar (gradient fill + sliding white marker)
221
+
222
+ ```kotlin
223
+ import androidx.compose.foundation.layout.BoxWithConstraints
224
+ import androidx.compose.foundation.shape.CircleShape
225
+ import androidx.compose.ui.graphics.Brush
226
+ import androidx.compose.ui.unit.Dp
227
+
228
+ @Composable
229
+ fun StrainBar(
230
+ currentStrain: Float, // 0f..21f
231
+ modifier: Modifier = Modifier,
232
+ height: Dp = 12.dp,
233
+ ) {
234
+ val fraction = (currentStrain / 21f).coerceIn(0f, 1f)
235
+ val animFraction by animateFloatAsState(
236
+ targetValue = fraction,
237
+ animationSpec = spring(dampingRatio = 0.7f, stiffness = 250f), // response ~0.5
238
+ label = "strainFill",
239
+ )
240
+ Column(verticalArrangement = Arrangement.spacedBy(6.dp)) {
241
+ // Tick labels at 8/10/14/18 → 0.4/0.5/0.7/0.9
242
+ BoxWithConstraints(Modifier.fillMaxWidth().height(14.dp)) {
243
+ val w = maxWidth
244
+ listOf(0.4f to "LOW", 0.5f to "MOD", 0.7f to "HIGH", 0.9f to "ALL-OUT").forEach { (pos, lbl) ->
245
+ Text(
246
+ lbl,
247
+ style = WhoopText.ChartAxis,
248
+ color = WhoopColors.Gray400,
249
+ modifier = Modifier.offset(x = w * pos),
250
+ )
251
+ }
252
+ }
253
+ BoxWithConstraints(Modifier.fillMaxWidth().height(height)) {
254
+ val w = maxWidth
255
+ Box(Modifier.fillMaxSize().clip(RoundedCornerShape(6.dp)).background(WhoopColors.Surface2))
256
+ Box(
257
+ Modifier
258
+ .fillMaxHeight()
259
+ .width(w * animFraction)
260
+ .clip(RoundedCornerShape(6.dp))
261
+ .background(
262
+ Brush.horizontalGradient(
263
+ listOf(WhoopColors.StrainDim, WhoopColors.Strain, WhoopColors.StrainBright)
264
+ )
265
+ )
266
+ )
267
+ Box(
268
+ Modifier
269
+ .offset(x = (w * animFraction - 8.dp).coerceAtLeast(0.dp))
270
+ .align(Alignment.CenterStart)
271
+ .size(16.dp)
272
+ .clip(CircleShape)
273
+ .background(WhoopColors.BrightWhite)
274
+ )
275
+ }
276
+ }
277
+ }
278
+ ```
279
+
280
+ ### Sleep Stage Chart (horizontal stacked bar)
281
+
282
+ ```kotlin
283
+ enum class SleepStage(val color: Color) {
284
+ Awake(WhoopColors.Gray600),
285
+ Light(WhoopColors.LightCyan),
286
+ Deep(WhoopColors.DeepIndigo),
287
+ Rem(WhoopColors.REMPurple),
288
+ }
289
+
290
+ data class SleepSegment(val stage: SleepStage, val durationMin: Int)
291
+
292
+ @Composable
293
+ fun SleepStageChart(
294
+ segments: List<SleepSegment>,
295
+ startLabel: String, // "11 PM"
296
+ endLabel: String, // "7 AM"
297
+ modifier: Modifier = Modifier,
298
+ ) {
299
+ val total = segments.sumOf { it.durationMin }.coerceAtLeast(1)
300
+ Column(modifier, verticalArrangement = Arrangement.spacedBy(6.dp)) {
301
+ Row(
302
+ Modifier
303
+ .fillMaxWidth()
304
+ .height(32.dp)
305
+ .clip(RoundedCornerShape(4.dp)),
306
+ horizontalArrangement = Arrangement.spacedBy(1.dp),
307
+ ) {
308
+ segments.forEach { seg ->
309
+ Box(
310
+ Modifier
311
+ .weight(seg.durationMin.toFloat() / total)
312
+ .fillMaxHeight()
313
+ .background(seg.stage.color)
314
+ )
315
+ }
316
+ }
317
+ Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
318
+ Text(startLabel, style = WhoopText.ChartAxis, color = WhoopColors.Gray400)
319
+ Text(endLabel, style = WhoopText.ChartAxis, color = WhoopColors.Gray400)
320
+ }
321
+ }
322
+ }
323
+ ```
324
+
325
+ ### Activity Row
326
+
327
+ ```kotlin
328
+ import androidx.compose.material.icons.Icons
329
+ import androidx.compose.material.icons.filled.ChevronRight
330
+ import androidx.compose.material.icons.filled.DirectionsRun
331
+ import androidx.compose.material3.Icon
332
+ import androidx.compose.ui.graphics.SolidColor
333
+
334
+ @Composable
335
+ fun ActivityRow(
336
+ icon: androidx.compose.ui.graphics.vector.ImageVector,
337
+ name: String,
338
+ strain: Float,
339
+ duration: String,
340
+ startTime: String,
341
+ onClick: () -> Unit,
342
+ modifier: Modifier = Modifier,
343
+ ) {
344
+ Column {
345
+ Row(
346
+ modifier = modifier
347
+ .fillMaxWidth()
348
+ .height(72.dp)
349
+ .background(WhoopColors.Canvas)
350
+ .clickable(onClick = onClick)
351
+ .padding(horizontal = 16.dp),
352
+ verticalAlignment = Alignment.CenterVertically,
353
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
354
+ ) {
355
+ Box(
356
+ Modifier
357
+ .size(40.dp)
358
+ .border(1.5.dp, WhoopColors.Strain, CircleShape),
359
+ contentAlignment = Alignment.Center,
360
+ ) {
361
+ Icon(icon, contentDescription = null, tint = WhoopColors.Strain, modifier = Modifier.size(18.dp))
362
+ }
363
+ Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(2.dp)) {
364
+ Text(name, style = WhoopText.CardTitle, color = WhoopColors.BrightWhite)
365
+ Text("%.1f".format(strain), style = WhoopText.MetricValue, color = WhoopColors.Strain)
366
+ }
367
+ Column(horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.spacedBy(2.dp)) {
368
+ Text(duration, style = WhoopText.Body, color = WhoopColors.SoftWhite)
369
+ Text(startTime, style = WhoopText.ChartAxis, color = WhoopColors.Gray400)
370
+ }
371
+ Icon(Icons.Filled.ChevronRight, contentDescription = null, tint = WhoopColors.Gray600, modifier = Modifier.size(12.dp))
372
+ }
373
+ Box(Modifier.fillMaxWidth().height(0.5.dp).background(WhoopColors.Divider))
374
+ }
375
+ }
376
+ ```
377
+
378
+ ### Metric Card (hairline border, no shadow)
379
+
380
+ ```kotlin
381
+ @Composable
382
+ fun MetricCard(label: String, modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit) {
383
+ Column(
384
+ modifier = modifier
385
+ .clip(RoundedCornerShape(12.dp))
386
+ .background(WhoopColors.Surface1)
387
+ .border(1.dp, WhoopColors.Divider, RoundedCornerShape(12.dp))
388
+ .padding(20.dp),
389
+ verticalArrangement = Arrangement.spacedBy(12.dp),
390
+ ) {
391
+ Text(label.uppercase(), style = WhoopText.MetricLabel, color = WhoopColors.Gray400)
392
+ content()
393
+ }
394
+ }
395
+ ```
396
+
397
+ ## 4. Recovery Ring (red→yellow→green interpolation) + Neon Glows
398
+
399
+ WHOOP's hero. The ring is **open at the top** (a small gap between stroke start and end), drawn with `Canvas`/`drawArc`. Its color is computed by score via `WhoopColors.recoveryColor`. Active/live elements get a **neon glow** instead of a neutral shadow — Android has no live blur, so approximate the iOS `rgba(0,255,123,0.18) 0 0 12px` halo with a stacked, blurred `Box` (`Modifier.blur` + `RenderEffect`) or a soft radial-gradient backdrop.
400
+
401
+ ```kotlin
402
+ import androidx.compose.foundation.Canvas
403
+ import androidx.compose.foundation.layout.Box
404
+ import androidx.compose.foundation.layout.size
405
+ import androidx.compose.ui.geometry.Offset
406
+ import androidx.compose.ui.geometry.Size
407
+ import androidx.compose.ui.graphics.StrokeCap
408
+ import androidx.compose.ui.graphics.drawscope.Stroke
409
+ import androidx.compose.ui.text.style.TextAlign
410
+ import androidx.compose.ui.unit.Dp
411
+
412
+ @Composable
413
+ fun RecoveryRing(
414
+ percent: Float, // 0f..100f
415
+ modifier: Modifier = Modifier,
416
+ diameter: Dp = 240.dp,
417
+ strokeWidth: Dp = 10.dp,
418
+ ) {
419
+ val animPercent by animateFloatAsState(
420
+ targetValue = percent,
421
+ animationSpec = spring(dampingRatio = 0.78f, stiffness = 80f), // ~1200ms ease-out w/ slight overshoot
422
+ label = "recoveryFill",
423
+ )
424
+ val ringColor = WhoopColors.recoveryColor(percent)
425
+
426
+ Box(modifier.size(diameter), contentAlignment = Alignment.Center) {
427
+ Canvas(Modifier.size(diameter)) {
428
+ val sw = strokeWidth.toPx()
429
+ val inset = sw / 2
430
+ val arcSize = Size(size.width - sw, size.height - sw)
431
+ val topLeft = Offset(inset, inset)
432
+ val gapDeg = 4f // ~2pt visual gap, "open" at top
433
+ val startAngle = -90f + gapDeg / 2f
434
+ val sweepFull = 360f - gapDeg
435
+ // Track
436
+ drawArc(
437
+ color = WhoopColors.Surface2,
438
+ startAngle = startAngle,
439
+ sweepAngle = sweepFull,
440
+ useCenter = false,
441
+ topLeft = topLeft,
442
+ size = arcSize,
443
+ style = Stroke(width = sw, cap = StrokeCap.Round),
444
+ )
445
+ // Fill — proportional to score
446
+ drawArc(
447
+ color = ringColor,
448
+ startAngle = startAngle,
449
+ sweepAngle = sweepFull * (animPercent / 100f),
450
+ useCenter = false,
451
+ topLeft = topLeft,
452
+ size = arcSize,
453
+ style = Stroke(width = sw, cap = StrokeCap.Round),
454
+ )
455
+ }
456
+ Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(4.dp)) {
457
+ Text("RECOVERY", style = WhoopText.SectionCaps, color = WhoopColors.Gray400)
458
+ Row(verticalAlignment = Alignment.Bottom) {
459
+ Text("${percent.toInt()}", style = WhoopText.RecoveryHero, color = WhoopColors.BrightWhite)
460
+ Text("%", style = WhoopText.SectionCaps.copy(fontSize = 24.sp), color = WhoopColors.BrightWhite)
461
+ }
462
+ }
463
+ }
464
+ }
465
+
466
+ /** Soft neon halo — Android's analog to iOS's `0 0 12px rgba(0,255,123,0.18)` glow. */
467
+ fun Modifier.neonGlow(color: Color, radius: Dp, alpha: Float): Modifier = this.then(
468
+ Modifier.drawBehind {
469
+ drawCircle(
470
+ brush = Brush.radialGradient(
471
+ colors = listOf(color.copy(alpha = alpha), Color.Transparent),
472
+ radius = radius.toPx(),
473
+ ),
474
+ radius = radius.toPx(),
475
+ )
476
+ }
477
+ )
478
+ ```
479
+
480
+ ### Live Workout Banner (heavy green glow + pulsing dot)
481
+
482
+ ```kotlin
483
+ import androidx.compose.animation.core.RepeatMode
484
+ import androidx.compose.animation.core.infiniteRepeatable
485
+ import androidx.compose.animation.core.rememberInfiniteTransition
486
+ import androidx.compose.animation.core.tween
487
+
488
+ @Composable
489
+ fun LiveWorkoutBanner(elapsed: String, currentStrain: Float, modifier: Modifier = Modifier) {
490
+ val t = rememberInfiniteTransition(label = "liveBanner")
491
+ val dotAlpha by t.animateFloat(
492
+ initialValue = 0.4f, targetValue = 1f,
493
+ animationSpec = infiniteRepeatable(tween(1200), RepeatMode.Reverse),
494
+ label = "dotPulse",
495
+ )
496
+ Row(
497
+ modifier = modifier
498
+ .fillMaxWidth()
499
+ .height(28.dp)
500
+ .background(WhoopColors.Strain)
501
+ .neonGlow(WhoopColors.Strain, radius = 48.dp, alpha = 0.32f)
502
+ .padding(horizontal = 16.dp),
503
+ verticalAlignment = Alignment.CenterVertically,
504
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
505
+ ) {
506
+ Box(
507
+ Modifier
508
+ .size(8.dp)
509
+ .clip(CircleShape)
510
+ .background(WhoopColors.Canvas.copy(alpha = dotAlpha))
511
+ )
512
+ Text(
513
+ "LIVE — $elapsed · STRAIN ${"%.1f".format(currentStrain)}",
514
+ style = WhoopText.MetaCaps,
515
+ color = WhoopColors.Canvas,
516
+ )
517
+ }
518
+ }
519
+ ```
520
+
521
+ ## 5. Bottom Navigation (Tab Bar)
522
+
523
+ Use Material 3 `NavigationBar` with the four canonical tabs (Overview, Coaching, Community, Stats). WHOOP's iOS tab bar uses `.systemThinMaterialDark` blur; Android has no first-class live blur, so use a 92%-opaque `Surface1`. **Active tint is Strain Green with a soft glow** — apply `neonGlow` behind the selected icon.
524
+
525
+ ```kotlin
526
+ import androidx.compose.material.icons.filled.BarChart
527
+ import androidx.compose.material.icons.filled.Dashboard
528
+ import androidx.compose.material.icons.filled.Groups
529
+ import androidx.compose.material.icons.filled.SelfImprovement
530
+ import androidx.compose.material3.NavigationBar
531
+ import androidx.compose.material3.NavigationBarItem
532
+ import androidx.compose.material3.NavigationBarItemDefaults
533
+
534
+ @Composable
535
+ fun WhoopBottomBar(selected: Int, onSelect: (Int) -> Unit) {
536
+ NavigationBar(
537
+ containerColor = WhoopColors.Surface1.copy(alpha = 0.92f),
538
+ tonalElevation = 0.dp,
539
+ ) {
540
+ val items = listOf(
541
+ "OVERVIEW" to Icons.Filled.Dashboard,
542
+ "COACHING" to Icons.Filled.SelfImprovement,
543
+ "COMMUNITY" to Icons.Filled.Groups,
544
+ "STATS" to Icons.Filled.BarChart,
545
+ )
546
+ items.forEachIndexed { i, (label, icon) ->
547
+ NavigationBarItem(
548
+ selected = selected == i,
549
+ onClick = { onSelect(i) },
550
+ icon = {
551
+ val m = if (selected == i)
552
+ Modifier.size(22.dp).neonGlow(WhoopColors.Strain, 18.dp, 0.18f)
553
+ else Modifier.size(22.dp)
554
+ Icon(icon, contentDescription = label, modifier = m)
555
+ },
556
+ label = { Text(label, style = WhoopText.Tab) },
557
+ alwaysShowLabel = true,
558
+ colors = NavigationBarItemDefaults.colors(
559
+ selectedIconColor = WhoopColors.Strain,
560
+ selectedTextColor = WhoopColors.Strain,
561
+ unselectedIconColor = WhoopColors.Gray600,
562
+ unselectedTextColor = WhoopColors.Gray600,
563
+ indicatorColor = Color.Transparent, // no Material pill — WHOOP has none
564
+ ),
565
+ )
566
+ }
567
+ }
568
+ }
569
+ ```
570
+
571
+ ## 6. Motion
572
+
573
+ | Moment | Compose recipe |
574
+ |--------|----------------|
575
+ | Recovery ring fill | `animateFloatAsState` with `spring(dampingRatio = 0.78f, stiffness = 80f)` — ~1200ms ease-out + slight overshoot |
576
+ | Strain marker slide | `animateFloatAsState` with `spring(dampingRatio = 0.7f, stiffness = 250f)` (iOS response 0.5) |
577
+ | Heart-rate beat pulse | `Animatable` keyframes `scale` 1 → 1.15 → 1 over 600ms, looped per beat |
578
+ | Live banner dot | `rememberInfiniteTransition` alpha 0.4 ↔ 1 every 1200ms |
579
+ | Day switcher tap | `animateFloatAsState` scale 1 → 1.08 (spring); `HapticFeedbackType.SegmentTick` |
580
+ | Primary CTA tap | scale 1 → 0.98 over 100ms, then `HapticFeedbackType.LongPress` (~medium impact) |
581
+ | Sleep segment tap | callout `AnimatedVisibility` `slideInVertically + fadeIn` 200ms; `HapticFeedbackType.TextHandleMove` |
582
+ | Sync complete | `Animatable` scale 1 → 1.3 → 1 once; `HapticFeedbackType.Confirm` (API 34) |
583
+
584
+ ```kotlin
585
+ // Heart-rate beat pulse — syncs the heart glyph to the live BPM
586
+ import androidx.compose.animation.core.Animatable
587
+ import androidx.compose.animation.core.keyframes
588
+
589
+ @Composable
590
+ fun HeartPulse(bpm: Int, content: @Composable () -> Unit) {
591
+ val scale = remember { Animatable(1f) }
592
+ LaunchedEffect(bpm) {
593
+ while (true) {
594
+ scale.animateTo(1.15f, keyframes { durationMillis = 200; 1.15f at 100 })
595
+ scale.animateTo(1f, tween(400))
596
+ kotlinx.coroutines.delay((60_000L / bpm.coerceAtLeast(40)) - 600)
597
+ }
598
+ }
599
+ Box(Modifier.scale(scale.value)) { content() }
600
+ }
601
+ ```
602
+
603
+ Haptics: prefer `LocalHapticFeedback`. `HapticFeedbackType.SegmentTick` ≈ iOS `.selection` for the day switcher and strain scrub; `HapticFeedbackType.LongPress` ≈ `.impact(.medium)` for CTAs. For richer control use `LocalView.current.performHapticFeedback(HapticFeedbackConstants.CONFIRM)` (API 30+) or a `Vibrator` `VibrationEffect.createOneShot(12, 80)`.
604
+
605
+ ## 7. Icons
606
+
607
+ WHOOP ships a **proprietary DIN-icon set** — none of the tab glyphs have exact Material twins. Use `androidx.compose.material:material-icons-extended` as a substitute and ship WHOOP's real glyphs as vector drawables loaded via `ImageVector.vectorResource(R.drawable.…)`.
608
+
609
+ | Purpose | SF Symbol (iOS) | Material Icon (Compose) |
610
+ |---------|-----------------|--------------------------|
611
+ | Overview tab | `circle.dashed` | `Icons.Filled.Dashboard` (or vector drawable) |
612
+ | Coaching tab | `person.crop.square` | `Icons.Filled.SelfImprovement` |
613
+ | Community tab | `person.3` | `Icons.Filled.Groups` |
614
+ | Stats tab | `chart.bar` | `Icons.Filled.BarChart` |
615
+ | Activity — run | `figure.run` | `Icons.Filled.DirectionsRun` |
616
+ | Activity — cycling | `figure.outdoor.cycle` | `Icons.Filled.DirectionsBike` |
617
+ | Activity — yoga | `figure.yoga` | `Icons.Filled.SelfImprovement` |
618
+ | Activity — strength | `dumbbell.fill` | `Icons.Filled.FitnessCenter` |
619
+ | Heart-rate live | `heart.fill` | `Icons.Filled.Favorite` |
620
+ | Battery | `battery.75` | `Icons.Filled.BatteryFull` |
621
+ | Sync | `arrow.triangle.2.circlepath` | `Icons.Filled.Sync` |
622
+ | Search | `magnifyingglass` | `Icons.Filled.Search` |
623
+ | Row chevron | `chevron.right` | `Icons.Filled.ChevronRight` |
624
+ | Live banner dot | `circle.fill` | `Icons.Filled.Circle` |
625
+
626
+ ## 8. Minimum SDK & Accessibility Notes
627
+
628
+ - **minSdk 24** (Compose floor is 21; `drawArc`, springs, and `RenderEffect` blur are comfortable at 24+; `Modifier.blur` for true glow needs API 31, so the radial-gradient `neonGlow` fallback covers 24–30). `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`.
629
+ - **Edge-to-edge**: call `enableEdgeToEdge()` in the `Activity` with light-content system bars (the canvas is near-black). The live workout banner should sit *above* the status-bar inset, replacing its background; apply `Scaffold` insets so the tab bar clears the gesture nav.
630
+ - **Font scaling**: `sp` honors the user's font scale — keep it on body, card titles, coaching headlines, and the large nav title. **Pin** every hero metric (76sp Recovery, 56sp Strain, 48sp Sleep), tab labels, chart axes, and metric labels by deriving them from a fixed-`fontScale` `LocalDensity` — they are layout-critical and the ring/bar geometry depends on them not reflowing.
631
+ - **TalkBack**: announce the Recovery ring as `"Recovery 73 percent, high recovery"`; the strain bar as `"Current strain 11.8 out of 21, high range"`; the sleep chart as a single merged node summarizing total + stage percentages. Use `Modifier.semantics(mergeDescendants = true)` on the activity row and CTA.
632
+ - **Touch targets**: Material guidance is 48.dp minimum. Day-switcher chips render at 36.dp visual — pad to 48.dp hit area. The primary CTA is already 48.dp; sleep-stage segments need a 24.dp minimum hit-width even when visually thinner.
633
+ - **Reduce Motion**: respect the system "remove animations" setting — skip the Recovery ring fill (snap to value), the heart-beat pulse, and the live-banner dot pulse; the day switcher should not scale.
634
+ - **Contrast**: Bright White on `#0A0A0A` exceeds AAA. Strain Green `#00FF7B` on `#0A0A0A` meets AA only at large/heavy sizes — keep it for short caps labels, ring/bar fills, and icons, **never body text**. `#A1A1AA` Gray400 is the secondary-text floor; do not push secondary text dimmer than this on the black canvas.
635
+ - **No light mode & no dynamic color**: there is no light scheme, and Material You `dynamicColorScheme()` must stay **off** — WHOOP's identity is the fixed black canvas, neon Strain Green, and the computed Recovery ramp regardless of wallpaper. Force the dark scheme at the root.