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,598 @@
1
+ # Nike Run Club (iOS) — Jetpack Compose Implementation Guide
2
+
3
+ Companion to [DESIGN.md](DESIGN.md) — the framework-neutral spec. This file ports NRC's visual language to **Android with Jetpack Compose (Material 3)**: a color token object, a `Typography` set, paste-ready `@Composable`s, the signature Volt run-tracking ring, 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 (NRC's true-black stadium void, radioactive Volt accent, screaming Trade Gothic Condensed) while making everything idiomatic Android — `NavigationBar` instead of a UITabBar, a `drawArc` `Canvas` ring instead of a SwiftUI `Circle().trim`, `sp`/`dp` instead of `pt`.
6
+
7
+ Assumes Compose BOM `2024.09+`, Kotlin `2.0+`, `minSdk 24`, Material 3, and [Coil](https://coil-kt.github.io/coil/) `2.6+` for plan-card photography. No color extraction — NRC's accent system is fixed Volt/Red, so Palette is not needed.
8
+
9
+ ## 1. Color Tokens
10
+
11
+ ```kotlin
12
+ // ui/theme/NikeColors.kt
13
+ import androidx.compose.ui.graphics.Color
14
+
15
+ object NikeColors {
16
+ // Nike Brand
17
+ val Volt = Color(0xFFCCFF00)
18
+ val VoltPressed = Color(0xFF9FCC00)
19
+ val VoltDim = Color(0xFF8AA800) // light-mode accessible accent
20
+ val Red = Color(0xFFFA5400)
21
+ val BrakeRed = Color(0xFFE50916)
22
+
23
+ // Canvas & Surfaces
24
+ val Canvas = Color(0xFF000000) // true black — Nike's stadium void
25
+ val Charcoal = Color(0xFF0A0A0A)
26
+ val Surface1 = Color(0xFF1A1A1A)
27
+ val Surface2 = Color(0xFF2B2B2B)
28
+ val Divider = Color(0xFF333333)
29
+
30
+ // Text
31
+ val White = Color(0xFFFFFFFF)
32
+ val Gray1 = Color(0xFFB3B3B3)
33
+ val Gray2 = Color(0xFF8E8E8E)
34
+ val Gray3 = Color(0xFF5C5C5C)
35
+
36
+ // Heart Rate Zones (workout results "training effect" page)
37
+ val HR1Blue = Color(0xFF3D87F4)
38
+ val HR2Green = Color(0xFF48C77E)
39
+ val HR3Yellow = Color(0xFFFFD600)
40
+ val HR4Orange = Color(0xFFFA5400) // same as Red
41
+ val HR5Red = Color(0xFFE50916)
42
+
43
+ // Semantic
44
+ val Warning = Color(0xFFFFC400)
45
+ }
46
+ ```
47
+
48
+ Wire it into a Material 3 `darkColorScheme` so ripples, dividers, and default component colors inherit the brand. NRC is dark-first by brand design; a light scheme exists only for accessibility — keep the app dark regardless of the system setting.
49
+
50
+ ```kotlin
51
+ // ui/theme/Theme.kt
52
+ import androidx.compose.material3.darkColorScheme
53
+ import androidx.compose.material3.MaterialTheme
54
+
55
+ private val NikeScheme = darkColorScheme(
56
+ primary = NikeColors.Volt,
57
+ onPrimary = NikeColors.Canvas, // black on Volt
58
+ secondary = NikeColors.Red,
59
+ background = NikeColors.Canvas,
60
+ onBackground = NikeColors.White,
61
+ surface = NikeColors.Surface1,
62
+ onSurface = NikeColors.White,
63
+ surfaceVariant = NikeColors.Surface2,
64
+ outline = NikeColors.Divider,
65
+ error = NikeColors.BrakeRed,
66
+ )
67
+
68
+ @Composable
69
+ fun NikeTheme(content: @Composable () -> Unit) =
70
+ MaterialTheme(colorScheme = NikeScheme, typography = NikeTypography, content = content)
71
+ ```
72
+
73
+ ## 2. Typography
74
+
75
+ Trade Gothic Next LT (Heavy/Bold Condensed) is proprietary (Linotype/Monotype). Drop the TTFs in `res/font/` (lowercase, snake_case) and build a `FontFamily`. Fall back to **Oswald** (a close geometric-condensed Google Font) or system condensed. Body/metadata use the system font (Roboto, the SF Pro analog). Stats are tabular — set `fontFeatureSettings = "tnum"`.
76
+
77
+ ```kotlin
78
+ // ui/theme/NikeType.kt
79
+ import androidx.compose.material3.Typography
80
+ import androidx.compose.ui.text.TextStyle
81
+ import androidx.compose.ui.text.font.Font
82
+ import androidx.compose.ui.text.font.FontFamily
83
+ import androidx.compose.ui.text.font.FontWeight
84
+ import androidx.compose.ui.unit.sp
85
+
86
+ val TradeGothic = FontFamily(
87
+ Font(R.font.trade_gothic_next_bold, FontWeight.Bold), // 700 Bold Condensed
88
+ Font(R.font.trade_gothic_next_heavy, FontWeight.Black), // 900 Heavy Condensed
89
+ )
90
+ // Body / metadata — system (Roboto) is the SF Pro analog
91
+ val NikeBodyFamily = FontFamily.Default
92
+
93
+ private const val TNUM = "tnum" // tabular digits — pace columns must align
94
+
95
+ // Named ramp — mirrors DESIGN.md §3 exactly (pt → sp 1:1, ALL CAPS at call sites)
96
+ object NikeText {
97
+ val RunHero = TextStyle(TradeGothic, fontWeight = FontWeight.Black, fontSize = 88.sp, lineHeight = 84.sp, letterSpacing = 0.5.sp, fontFeatureSettings = TNUM)
98
+ val PreHero = TextStyle(TradeGothic, fontWeight = FontWeight.Black, fontSize = 64.sp, lineHeight = 61.sp, letterSpacing = 0.4.sp, fontFeatureSettings = TNUM)
99
+ val Headline = TextStyle(TradeGothic, fontWeight = FontWeight.Black, fontSize = 48.sp, lineHeight = 46.sp, letterSpacing = 0.3.sp)
100
+ val ScreamHdr = TextStyle(TradeGothic, fontWeight = FontWeight.Black, fontSize = 32.sp, lineHeight = 32.sp, letterSpacing = 0.3.sp)
101
+ val SubHdr = TextStyle(TradeGothic, fontWeight = FontWeight.Bold, fontSize = 22.sp, lineHeight = 24.sp, letterSpacing = 0.3.sp)
102
+ val StatLabel = TextStyle(TradeGothic, fontWeight = FontWeight.Bold, fontSize = 13.sp, lineHeight = 13.sp, letterSpacing = 1.0.sp)
103
+ val StatValue = TextStyle(TradeGothic, fontWeight = FontWeight.Black, fontSize = 64.sp, lineHeight = 61.sp, letterSpacing = 0.4.sp, fontFeatureSettings = TNUM)
104
+ val Button = TextStyle(TradeGothic, fontWeight = FontWeight.Black, fontSize = 17.sp, lineHeight = 17.sp, letterSpacing = 0.5.sp)
105
+ val Achievement = TextStyle(TradeGothic, fontWeight = FontWeight.Black, fontSize = 56.sp, lineHeight = 53.sp, fontFeatureSettings = TNUM)
106
+
107
+ // SF Pro analog (Roboto) for body / metadata — mixed case allowed
108
+ val CardTitle = TextStyle(NikeBodyFamily, fontWeight = FontWeight.Bold, fontSize = 17.sp, lineHeight = 20.sp, letterSpacing = (-0.2).sp)
109
+ val Body = TextStyle(NikeBodyFamily, fontWeight = FontWeight.Normal, fontSize = 15.sp, lineHeight = 22.sp, letterSpacing = (-0.1).sp)
110
+ val BodyBold = TextStyle(NikeBodyFamily, fontWeight = FontWeight.SemiBold, fontSize = 15.sp, lineHeight = 22.sp, letterSpacing = (-0.1).sp)
111
+ val Meta = TextStyle(NikeBodyFamily, fontWeight = FontWeight.Normal, fontSize = 13.sp, lineHeight = 17.sp)
112
+ val Caption = TextStyle(NikeBodyFamily, fontWeight = FontWeight.Medium, fontSize = 11.sp, lineHeight = 14.sp, letterSpacing = 0.1.sp)
113
+ val Tab = TextStyle(NikeBodyFamily, fontWeight = FontWeight.SemiBold, fontSize = 10.sp, lineHeight = 10.sp, letterSpacing = 0.3.sp)
114
+ }
115
+
116
+ // Map onto Material 3 slots so stock components inherit the brand
117
+ val NikeTypography = Typography(
118
+ displayLarge = NikeText.RunHero,
119
+ headlineLarge = NikeText.ScreamHdr,
120
+ titleMedium = NikeText.CardTitle,
121
+ bodyMedium = NikeText.Body,
122
+ labelSmall = NikeText.Tab,
123
+ )
124
+ ```
125
+
126
+ ## 3. Signature Components
127
+
128
+ ### Primary Action Button ("START RUN" / "LET'S DO THIS" / "FINISH")
129
+
130
+ ```kotlin
131
+ import androidx.compose.animation.core.animateFloatAsState
132
+ import androidx.compose.animation.core.spring
133
+ import androidx.compose.foundation.background
134
+ import androidx.compose.foundation.border
135
+ import androidx.compose.foundation.clickable
136
+ import androidx.compose.foundation.interaction.MutableInteractionSource
137
+ import androidx.compose.foundation.interaction.collectIsPressedAsState
138
+ import androidx.compose.foundation.layout.*
139
+ import androidx.compose.foundation.shape.RoundedCornerShape
140
+ import androidx.compose.material3.Text
141
+ import androidx.compose.runtime.*
142
+ import androidx.compose.ui.Alignment
143
+ import androidx.compose.ui.Modifier
144
+ import androidx.compose.ui.draw.clip
145
+ import androidx.compose.ui.draw.scale
146
+ import androidx.compose.ui.graphics.Color
147
+ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
148
+ import androidx.compose.ui.platform.LocalHapticFeedback
149
+ import androidx.compose.ui.unit.dp
150
+
151
+ enum class NikeButtonStyle { White, Volt, Outline }
152
+
153
+ @Composable
154
+ fun NikeActionButton(
155
+ title: String, // pass already-UPPERCASE
156
+ onClick: () -> Unit,
157
+ modifier: Modifier = Modifier,
158
+ style: NikeButtonStyle = NikeButtonStyle.White,
159
+ ) {
160
+ val interaction = remember { MutableInteractionSource() }
161
+ val pressed by interaction.collectIsPressedAsState()
162
+ val scale by animateFloatAsState(
163
+ targetValue = if (pressed) 0.98f else 1f,
164
+ animationSpec = spring(dampingRatio = 0.7f, stiffness = 700f),
165
+ label = "ctaScale",
166
+ )
167
+ val haptics = LocalHapticFeedback.current
168
+ val bg = when (style) {
169
+ NikeButtonStyle.White -> NikeColors.White
170
+ NikeButtonStyle.Volt -> NikeColors.Volt
171
+ NikeButtonStyle.Outline -> Color.Transparent
172
+ }
173
+ val fg = if (style == NikeButtonStyle.Outline) NikeColors.White else NikeColors.Canvas
174
+
175
+ Box(
176
+ modifier = modifier
177
+ .fillMaxWidth()
178
+ .height(56.dp)
179
+ .scale(scale)
180
+ .clip(RoundedCornerShape(32.dp)) // very rounded, not a full pill
181
+ .background(bg)
182
+ .then(if (style == NikeButtonStyle.Outline) Modifier.border(2.dp, NikeColors.White, RoundedCornerShape(32.dp)) else Modifier)
183
+ .clickable(interaction, indication = null) {
184
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // heaviest — Nike's committed CTA
185
+ onClick()
186
+ },
187
+ contentAlignment = Alignment.Center,
188
+ ) {
189
+ Text(title, style = NikeText.Button, color = fg)
190
+ }
191
+ }
192
+ ```
193
+
194
+ ### Volt Progress Ring + Run Tracking Screen
195
+
196
+ ```kotlin
197
+ import androidx.compose.foundation.Canvas
198
+ import androidx.compose.ui.geometry.Size
199
+ import androidx.compose.ui.graphics.StrokeCap
200
+ import androidx.compose.ui.graphics.drawscope.Stroke
201
+
202
+ @Composable
203
+ fun VoltProgressRing(
204
+ progress: Float, // 0f..1f
205
+ modifier: Modifier = Modifier,
206
+ diameter: Dp = 280.dp,
207
+ strokeWidth: Dp = 6.dp,
208
+ ) {
209
+ val animated by animateFloatAsState(
210
+ targetValue = progress.coerceIn(0f, 1f),
211
+ animationSpec = spring(stiffness = 50f), // smooth fill toward the goal
212
+ label = "ringProgress",
213
+ )
214
+ Canvas(modifier.size(diameter)) {
215
+ val sw = strokeWidth.toPx()
216
+ val inset = sw / 2
217
+ val arcSize = Size(size.width - sw, size.height - sw)
218
+ // Track
219
+ drawArc(
220
+ color = NikeColors.White.copy(alpha = 0.1f),
221
+ startAngle = 0f, sweepAngle = 360f, useCenter = false,
222
+ topLeft = androidx.compose.ui.geometry.Offset(inset, inset),
223
+ size = arcSize,
224
+ style = Stroke(width = sw, cap = StrokeCap.Round),
225
+ )
226
+ // Volt fill — starts at 12 o'clock (-90°), clockwise
227
+ drawArc(
228
+ color = NikeColors.Volt,
229
+ startAngle = -90f, sweepAngle = 360f * animated, useCenter = false,
230
+ topLeft = androidx.compose.ui.geometry.Offset(inset, inset),
231
+ size = arcSize,
232
+ style = Stroke(width = sw, cap = StrokeCap.Round),
233
+ )
234
+ }
235
+ }
236
+
237
+ @Composable
238
+ fun NRCStat(label: String, value: String, modifier: Modifier = Modifier) {
239
+ Column(modifier, horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(4.dp)) {
240
+ Text(label.uppercase(), style = NikeText.StatLabel, color = NikeColors.White.copy(alpha = 0.7f))
241
+ Text(value, style = NikeText.StatValue, color = NikeColors.White)
242
+ }
243
+ }
244
+
245
+ @Composable
246
+ fun RunTrackingScreen(
247
+ elapsed: String, // "12:34"
248
+ distance: String, // "1.4"
249
+ pace: String, // "8:42"
250
+ hr: String, // "152"
251
+ progress: Float,
252
+ paused: Boolean,
253
+ onPauseToggle: () -> Unit,
254
+ onLock: () -> Unit,
255
+ ) {
256
+ val haptics = LocalHapticFeedback.current
257
+ Box(
258
+ Modifier.fillMaxSize().background(NikeColors.Canvas),
259
+ contentAlignment = Alignment.TopCenter,
260
+ ) {
261
+ Column(
262
+ Modifier.fillMaxSize().padding(top = 64.dp),
263
+ horizontalAlignment = Alignment.CenterHorizontally,
264
+ verticalArrangement = Arrangement.spacedBy(32.dp),
265
+ ) {
266
+ Row(
267
+ Modifier.fillMaxWidth().padding(horizontal = 24.dp),
268
+ horizontalArrangement = Arrangement.SpaceBetween,
269
+ ) {
270
+ NRCStat("Distance", distance, Modifier.weight(1f))
271
+ NRCStat("Min/Mi", pace, Modifier.weight(1f))
272
+ NRCStat("BPM", hr, Modifier.weight(1f))
273
+ }
274
+ Box(contentAlignment = Alignment.Center) {
275
+ VoltProgressRing(progress)
276
+ Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(4.dp)) {
277
+ Text(elapsed, style = NikeText.RunHero, color = NikeColors.White)
278
+ Text("ELAPSED", style = NikeText.StatLabel, color = NikeColors.White.copy(alpha = 0.7f))
279
+ }
280
+ }
281
+ Spacer(Modifier.weight(1f))
282
+ Row(
283
+ Modifier.fillMaxWidth().padding(bottom = 48.dp, end = 16.dp),
284
+ horizontalArrangement = Arrangement.Center,
285
+ verticalAlignment = Alignment.CenterVertically,
286
+ ) {
287
+ Box(
288
+ Modifier
289
+ .size(72.dp)
290
+ .clip(androidx.compose.foundation.shape.CircleShape)
291
+ .background(if (paused) NikeColors.Volt else NikeColors.White)
292
+ .clickable {
293
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // heavy
294
+ onPauseToggle()
295
+ },
296
+ contentAlignment = Alignment.Center,
297
+ ) {
298
+ Icon(
299
+ if (paused) Icons.Filled.PlayArrow else Icons.Filled.Pause,
300
+ contentDescription = if (paused) "Resume" else "Pause",
301
+ tint = NikeColors.Canvas,
302
+ modifier = Modifier.size(28.dp),
303
+ )
304
+ }
305
+ }
306
+ }
307
+ }
308
+ }
309
+ ```
310
+
311
+ ### Run Plan Card (Home Feed)
312
+
313
+ ```kotlin
314
+ import coil.compose.AsyncImage
315
+ import androidx.compose.ui.graphics.Brush
316
+ import androidx.compose.ui.layout.ContentScale
317
+
318
+ @Composable
319
+ fun RunPlanCard(
320
+ photoUrl: String,
321
+ eyebrow: String, // "GUIDED RUN · 25 MIN"
322
+ title: String, // "RECOVERY MILE"
323
+ description: String, // "Coach Bennett · Easy effort"
324
+ onClick: () -> Unit,
325
+ modifier: Modifier = Modifier,
326
+ ) {
327
+ val interaction = remember { MutableInteractionSource() }
328
+ val pressed by interaction.collectIsPressedAsState()
329
+ val scale by animateFloatAsState(if (pressed) 0.98f else 1f, label = "planScale")
330
+ val haptics = LocalHapticFeedback.current
331
+
332
+ Box(
333
+ modifier
334
+ .fillMaxWidth()
335
+ .padding(horizontal = 16.dp)
336
+ .height(320.dp)
337
+ .scale(scale)
338
+ .clip(RoundedCornerShape(16.dp)) // no shadow — Nike is flat on black
339
+ .clickable(interaction, indication = null) {
340
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove)
341
+ onClick()
342
+ },
343
+ contentAlignment = Alignment.BottomStart,
344
+ ) {
345
+ AsyncImage(model = photoUrl, contentDescription = null, modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop)
346
+ Box(
347
+ Modifier
348
+ .fillMaxSize()
349
+ .background(Brush.verticalGradient(listOf(Color.Transparent, Color.Black.copy(alpha = 0.6f), Color.Black.copy(alpha = 0.85f)))),
350
+ )
351
+ Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
352
+ Text(eyebrow.uppercase(), style = NikeText.Caption, color = NikeColors.White.copy(alpha = 0.8f))
353
+ Text(title.uppercase(), style = NikeText.ScreamHdr, color = NikeColors.White)
354
+ Text(description, style = NikeText.Meta, color = NikeColors.White.copy(alpha = 0.85f))
355
+ }
356
+ }
357
+ }
358
+ ```
359
+
360
+ ### Achievement Medal (hexagonal reveal)
361
+
362
+ ```kotlin
363
+ import androidx.compose.animation.core.Animatable
364
+ import androidx.compose.ui.graphics.Path
365
+ import androidx.compose.ui.graphics.drawscope.DrawScope
366
+
367
+ fun DrawScope.hexagonPath(): Path = Path().apply {
368
+ val w = size.width; val h = size.height
369
+ moveTo(w * 0.5f, 0f)
370
+ lineTo(w, h * 0.25f)
371
+ lineTo(w, h * 0.75f)
372
+ lineTo(w * 0.5f, h)
373
+ lineTo(0f, h * 0.75f)
374
+ lineTo(0f, h * 0.25f)
375
+ close()
376
+ }
377
+
378
+ @Composable
379
+ fun AchievementMedal(
380
+ milestone: String, // "100"
381
+ label: String, // "100 MILES"
382
+ subtitle: String, // "Lifetime distance"
383
+ ) {
384
+ val scale = remember { Animatable(0.5f) }
385
+ val alpha = remember { Animatable(0f) }
386
+ val haptics = LocalHapticFeedback.current
387
+ LaunchedEffect(Unit) {
388
+ haptics.performHapticFeedback(HapticFeedbackType.Confirm) // .success analog
389
+ alpha.animateTo(1f, spring(stiffness = 200f))
390
+ scale.animateTo(1f, spring(dampingRatio = 0.6f, stiffness = 400f))
391
+ }
392
+ Column(
393
+ Modifier.padding(24.dp),
394
+ horizontalAlignment = Alignment.CenterHorizontally,
395
+ verticalArrangement = Arrangement.spacedBy(16.dp),
396
+ ) {
397
+ Box(contentAlignment = Alignment.Center) {
398
+ Canvas(
399
+ Modifier
400
+ .size(200.dp)
401
+ .scale(scale.value)
402
+ .graphicsLayer { this.alpha = alpha.value },
403
+ ) {
404
+ drawPath(
405
+ hexagonPath(),
406
+ brush = Brush.linearGradient(listOf(NikeColors.Volt, NikeColors.Red)),
407
+ )
408
+ }
409
+ Text(milestone, style = NikeText.Achievement, color = NikeColors.Canvas, modifier = Modifier.scale(scale.value))
410
+ }
411
+ Text(label.uppercase(), style = NikeText.SubHdr, color = NikeColors.White)
412
+ Text(subtitle, style = NikeText.Body, color = NikeColors.Gray1)
413
+ }
414
+ }
415
+ ```
416
+
417
+ ### Heart Rate Zone Bar
418
+
419
+ ```kotlin
420
+ @Composable
421
+ fun HRZoneBar(times: List<Float>, modifier: Modifier = Modifier) {
422
+ val zones = listOf(
423
+ NikeColors.HR1Blue to "Z1 Easy",
424
+ NikeColors.HR2Green to "Z2 Steady",
425
+ NikeColors.HR3Yellow to "Z3 Mod",
426
+ NikeColors.HR4Orange to "Z4 Hard",
427
+ NikeColors.HR5Red to "Z5 Max",
428
+ )
429
+ val total = times.sum().coerceAtLeast(1f)
430
+ Column(modifier, verticalArrangement = Arrangement.spacedBy(12.dp)) {
431
+ Row(
432
+ Modifier.fillMaxWidth().height(8.dp).clip(RoundedCornerShape(4.dp)),
433
+ ) {
434
+ times.forEachIndexed { i, t ->
435
+ Box(Modifier.fillMaxHeight().weight((t / total).coerceAtLeast(0.001f)).background(zones[i].first))
436
+ }
437
+ }
438
+ Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
439
+ zones.forEach { (c, label) ->
440
+ Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp)) {
441
+ Box(Modifier.size(6.dp).clip(androidx.compose.foundation.shape.CircleShape).background(c))
442
+ Text(label.uppercase(), style = NikeText.Caption, color = NikeColors.White)
443
+ }
444
+ }
445
+ }
446
+ }
447
+ }
448
+ ```
449
+
450
+ ## 4. The Volt Progress Ring (signature interaction)
451
+
452
+ The 280.dp Volt ring inside the Run Tracking screen is NRC's defining moment — the closest a phone gets to feeling like a piece of equipment. Implemented above in §3 via `Canvas` + `drawArc`: a `rgba(255,255,255,0.1)` full-circle track, a Volt sweep from `-90°` (12 o'clock) clockwise, both with `StrokeCap.Round` (never sharp caps). The 88.sp Trade Gothic elapsed time sits dead-center, cropped tight by the `84.sp` line height so it kisses the ring's inner edge — that tight crop is intentional Nike.
453
+
454
+ Drive `progress` from the run goal and let the ring tick discretely per mile/km/interval:
455
+
456
+ ```kotlin
457
+ // In the run ViewModel — emit progress toward the goal each tick
458
+ val progress by produceState(0f, distanceMeters, goalMeters) {
459
+ value = (distanceMeters / goalMeters).coerceIn(0f, 1f)
460
+ }
461
+ // Pass straight into VoltProgressRing(progress) — the spring(stiffness = 50f) gives the
462
+ // smooth linear-feeling fill; for hard 1s ticks per unit swap to tween(1000, easing = LinearEasing).
463
+ ```
464
+
465
+ A `lock` affordance (48.dp `Surface2` circle, white lock glyph, top-right inset 16.dp) disables accidental mid-run taps; render it as an overlay aligned `Alignment.TopEnd`.
466
+
467
+ ## 5. Bottom Navigation (Tab Bar)
468
+
469
+ Use Material 3 `NavigationBar`. NRC's iOS tab bar is a plain black bar with a 0.5pt `#333333` hairline — Android has no live blur but none is needed here (the bar is opaque `#000000`). 5 tabs: Home / Activity / Coach / Goal / Profile. Active is **white icon + a 4.dp Volt dot** under it; Material's pill indicator is suppressed.
470
+
471
+ ```kotlin
472
+ @Composable
473
+ fun NikeBottomBar(selected: Int, onSelect: (Int) -> Unit) {
474
+ val haptics = LocalHapticFeedback.current
475
+ NavigationBar(
476
+ containerColor = NikeColors.Canvas,
477
+ tonalElevation = 0.dp,
478
+ ) {
479
+ val items = listOf(
480
+ "Home" to Icons.Filled.Home,
481
+ "Activity" to Icons.Filled.BarChart,
482
+ "Coach" to Icons.Filled.Person,
483
+ "Goal" to Icons.Filled.TrackChanges,
484
+ "Profile" to Icons.Filled.AccountCircle,
485
+ )
486
+ items.forEachIndexed { i, (label, icon) ->
487
+ val active = selected == i
488
+ NavigationBarItem(
489
+ selected = active,
490
+ onClick = {
491
+ haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove) // .selection — never heavy on tabs
492
+ onSelect(i)
493
+ },
494
+ icon = {
495
+ Column(horizontalAlignment = Alignment.CenterHorizontally) {
496
+ Icon(icon, contentDescription = label, modifier = Modifier.size(24.dp))
497
+ Spacer(Modifier.height(4.dp))
498
+ Box(
499
+ Modifier
500
+ .size(4.dp)
501
+ .clip(androidx.compose.foundation.shape.CircleShape)
502
+ .background(if (active) NikeColors.Volt else Color.Transparent),
503
+ )
504
+ }
505
+ },
506
+ label = { Text(label, style = NikeText.Tab) },
507
+ colors = NavigationBarItemDefaults.colors(
508
+ selectedIconColor = NikeColors.White,
509
+ selectedTextColor = NikeColors.White,
510
+ unselectedIconColor = NikeColors.Gray3, // #5C5C5C
511
+ unselectedTextColor = NikeColors.Gray2, // #8E8E8E
512
+ indicatorColor = Color.Transparent, // no Material pill — NRC uses a Volt dot
513
+ ),
514
+ )
515
+ }
516
+ }
517
+ }
518
+ ```
519
+
520
+ ## 6. Motion
521
+
522
+ NRC motion is deterministic and committed — linear ticks on the ring, heavy haptics on commitment, springy medal reveals.
523
+
524
+ | Moment | Compose recipe |
525
+ |--------|----------------|
526
+ | Progress ring fill | `animateFloatAsState` `spring(stiffness = 50f)`, or `tween(1000, LinearEasing)` for hard per-unit ticks |
527
+ | START RUN tap | scale 1 → 0.98 `spring(0.7f)` + `HapticFeedbackType.LongPress` (heaviest), then 400ms `Crossfade` to Run Tracking |
528
+ | Pause tap | circle scale 1 → 0.95 + heavy haptic, morph to Resume (Volt) + Stop (red) over 250ms spring |
529
+ | Achievement reveal | `Animatable` scale 0.5 → 1 `spring(response 0.4, damping 0.6)` + alpha fade + Confirm haptic; confetti burst |
530
+ | Tab switch | Volt dot slides via `SharedTransitionLayout`/`animateDpAsState`, icon cross-fades 200ms, `TextHandleMove` haptic |
531
+ | PR confetti | 16-particle Volt burst + `LongPress` heavy haptic |
532
+
533
+ ```kotlin
534
+ // Volt confetti burst on a PR / milestone — 16 particles
535
+ @Composable
536
+ fun VoltConfetti(trigger: Boolean) {
537
+ val haptics = LocalHapticFeedback.current
538
+ val t = remember { Animatable(0f) }
539
+ LaunchedEffect(trigger) {
540
+ if (trigger) {
541
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress) // heavy
542
+ t.snapTo(0f); t.animateTo(1f, tween(600))
543
+ }
544
+ }
545
+ Canvas(Modifier.fillMaxSize()) {
546
+ if (t.value == 0f) return@Canvas
547
+ val cx = size.width / 2; val cy = size.height / 2
548
+ repeat(16) { i ->
549
+ val angle = (i / 16f) * 2f * Math.PI
550
+ val r = 320f * t.value
551
+ drawCircle(
552
+ color = NikeColors.Volt.copy(alpha = 1f - t.value),
553
+ radius = 6f,
554
+ center = androidx.compose.ui.geometry.Offset(
555
+ cx + (r * kotlin.math.cos(angle)).toFloat(),
556
+ cy + (r * kotlin.math.sin(angle)).toFloat(),
557
+ ),
558
+ )
559
+ }
560
+ }
561
+ }
562
+ ```
563
+
564
+ Haptics: prefer `LocalHapticFeedback`. For the heaviest "START RUN"/"PAUSE" feel use `LocalView.current.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)` or a `Vibrator` `VibrationEffect.createOneShot(25, VibrationEffect.DEFAULT_AMPLITUDE)`.
565
+
566
+ ## 7. Icons
567
+
568
+ NRC ships custom glyphs; the closest first-party set is `androidx.compose.material:material-icons-extended`. The hexagonal medal is NOT an icon — draw it via `Canvas` (§3); the Volt active-tab dot is also drawn, not an icon.
569
+
570
+ | Purpose | SF Symbol (iOS) | Material Icon (Compose) |
571
+ |---------|-----------------|--------------------------|
572
+ | Pause | `pause.fill` | `Icons.Filled.Pause` |
573
+ | Play / Resume | `play.fill` | `Icons.Filled.PlayArrow` |
574
+ | Stop | `stop.fill` | `Icons.Filled.Stop` |
575
+ | Lock | `lock.fill` | `Icons.Filled.Lock` |
576
+ | GPS strength | `location.fill` | `Icons.Filled.LocationOn` |
577
+ | Coach Bennett | `person.crop.circle.fill` | `Icons.Filled.AccountCircle` |
578
+ | Home (tab) | `house` / `house.fill` | `Icons.Filled.Home` |
579
+ | Activity (tab) | `chart.bar` / `.fill` | `Icons.Filled.BarChart` |
580
+ | Coach (tab) | `person.crop.square` / `.fill` | `Icons.Filled.Person` |
581
+ | Goal (tab) | `target` | `Icons.Filled.TrackChanges` |
582
+ | Profile (tab) | `person.circle` / `.fill` | `Icons.Filled.AccountCircle` |
583
+ | Heart rate | `heart.fill` | `Icons.Filled.Favorite` |
584
+ | Share | `square.and.arrow.up` | `Icons.Filled.IosShare` |
585
+ | Settings | `gearshape.fill` | `Icons.Filled.Settings` |
586
+ | Music | `music.note` | `Icons.Filled.MusicNote` |
587
+
588
+ ## 8. Minimum SDK & Accessibility Notes
589
+
590
+ - **minSdk 24** (Compose floor is 21; `Canvas`-based ring + modern motion are comfortable at 24). `compileSdk 34+`, Compose BOM `2024.09+`, Kotlin `2.0+`.
591
+ - **Edge-to-edge**: call `enableEdgeToEdge()` in the `Activity`; the true-black canvas wants `WindowCompat` light-content system bars. The top app bar / Run Tracking stats sit below the camera cutout; the pause control respects the gesture-nav inset via `Scaffold`/`windowInsetsPadding`.
592
+ - **Font scaling**: `sp` honors the user's font scale automatically — scale body, metadata, and plan-card titles. Pin the visual identity (88sp `RunHero`, 64sp `StatValue`, 17sp `Button`, 13sp `StatLabel`, 10sp tab labels) by deriving size from `dp` or wrapping in `CompositionLocalProvider(LocalDensity provides Density(density, fontScale = 1f))` — NRC's identity depends on these exact sizes.
593
+ - **Tabular digits**: keep `fontFeatureSettings = "tnum"` on every stat (pace, distance, elapsed, BPM, splits) so columns align on the results page.
594
+ - **TalkBack**: make the Run Tracking screen read each stat as a separate node so a user can spot-check one at a time — e.g. "Run in progress, 12 minutes 34 seconds elapsed", "1.4 miles", "8 minute 42 second per mile pace", "heart rate 152 BPM", then "Pause button". Use `Modifier.semantics { contentDescription = ... }` per stat.
595
+ - **Touch targets**: Material guidance is 48.dp minimum. The 72.dp pause circle and 56.dp CTA clear it; give the 48.dp lock circle its full hit area.
596
+ - **Contrast**: Volt `#CCFF00` on `#000000` passes WCAG AAA at all sizes; Volt on white FAILS — use `VoltDim` `#8AA800` on any light surface. `#8E8E8E` tab labels on black pass AA at 10sp+; validate the 11sp `Caption`.
597
+ - **Reduce motion**: when `Settings.Global.ANIMATOR_DURATION_SCALE == 0`, skip the medal scale spring and the confetti burst — fade the medal in over 300ms with no scale change; keep the ring fill (it conveys state, not decoration).
598
+ - **Dynamic color**: do **not** enable Material You `dynamicDarkColorScheme()` — NRC's brand requires the fixed `#000000` canvas and the radioactive `#CCFF00` Volt regardless of wallpaper. Keep the app dark even when the system is light (light mode is an accessibility-only fallback using `VoltDim`).