@palate/cli 0.0.0-stage → 0.0.1

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 (1222) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +151 -2
  3. package/bin/palate.mjs +894 -0
  4. package/kb/anatomy/data-table.md +24 -0
  5. package/kb/anatomy/empty-state.md +16 -0
  6. package/kb/anatomy/filter-toolbar.md +19 -0
  7. package/kb/anatomy/meter.md +16 -0
  8. package/kb/anatomy/product-window.md +18 -0
  9. package/kb/anatomy/settings-page.md +18 -0
  10. package/kb/anatomy/status-indicator.md +17 -0
  11. package/kb/anatomy/toast-undo.md +16 -0
  12. package/kb/bench/briefs.json +618 -0
  13. package/kb/craft/SOURCES.md +48 -0
  14. package/kb/craft/creativity.md +55 -0
  15. package/kb/craft/details.md +75 -0
  16. package/kb/craft/landing-demos.md +46 -0
  17. package/kb/craft/mistakes.md +73 -0
  18. package/kb/craft/motion.md +53 -0
  19. package/kb/craft/principles.md +68 -0
  20. package/kb/index/discovery.json +1 -0
  21. package/kb/inspiration/index.json +79 -0
  22. package/kb/moves/animated-comparison-table.md +58 -0
  23. package/kb/moves/before-after-slider.md +58 -0
  24. package/kb/moves/bento-live-tiles.md +57 -0
  25. package/kb/moves/calm-motion-system.md +63 -0
  26. package/kb/moves/canvas-grain.md +58 -0
  27. package/kb/moves/changelog-as-magazine.md +56 -0
  28. package/kb/moves/code-drawn-diagram.md +56 -0
  29. package/kb/moves/colophon.md +54 -0
  30. package/kb/moves/command-palette-site-nav.md +58 -0
  31. package/kb/moves/confetti-free-celebration.md +58 -0
  32. package/kb/moves/console-easter-egg.md +57 -0
  33. package/kb/moves/copy-confirmation.md +57 -0
  34. package/kb/moves/cursor-reactive-light.md +57 -0
  35. package/kb/moves/dark-band-contrast-section.md +55 -0
  36. package/kb/moves/designed-dark-mode.md +58 -0
  37. package/kb/moves/duotone-photography.md +55 -0
  38. package/kb/moves/editorial-drop-cap.md +58 -0
  39. package/kb/moves/editorial-grid-pull-quotes.md +55 -0
  40. package/kb/moves/engraving-colour-lens.md +64 -0
  41. package/kb/moves/explorable-control.md +57 -0
  42. package/kb/moves/feature-films-on-painted-stages.md +58 -0
  43. package/kb/moves/first-win-onboarding.md +59 -0
  44. package/kb/moves/footer-live-status.md +56 -0
  45. package/kb/moves/footer-rewards-the-end.md +58 -0
  46. package/kb/moves/generative-brand-pattern.md +55 -0
  47. package/kb/moves/gentle-error-nudge.md +59 -0
  48. package/kb/moves/halftone-dot-imagery.md +55 -0
  49. package/kb/moves/hand-drawn-annotations.md +55 -0
  50. package/kb/moves/hero-paints-itself-in.md +65 -0
  51. package/kb/moves/honest-progress-narration.md +58 -0
  52. package/kb/moves/honest-testimonial-wall.md +57 -0
  53. package/kb/moves/inline-sparklines-in-copy.md +57 -0
  54. package/kb/moves/inspect-our-taste.md +58 -0
  55. package/kb/moves/interactive-pricing-calculator.md +59 -0
  56. package/kb/moves/isometric-illustration-system.md +56 -0
  57. package/kb/moves/kinetic-variable-type.md +57 -0
  58. package/kb/moves/konami-secret.md +59 -0
  59. package/kb/moves/layered-paper-depth.md +56 -0
  60. package/kb/moves/lightweight-3d-object-hero.md +59 -0
  61. package/kb/moves/line-engraving-from-image.md +63 -0
  62. package/kb/moves/link-preview-peek.md +57 -0
  63. package/kb/moves/live-data-ticker.md +61 -0
  64. package/kb/moves/made-with-proof.md +51 -0
  65. package/kb/moves/magnetic-buttons.md +55 -0
  66. package/kb/moves/marquee-done-right.md +58 -0
  67. package/kb/moves/moves.yaml +450 -0
  68. package/kb/moves/museum-painting-backdrop.md +59 -0
  69. package/kb/moves/one-colour-brand-world.md +56 -0
  70. package/kb/moves/playful-404.md +58 -0
  71. package/kb/moves/pointer-highlight-word.md +56 -0
  72. package/kb/moves/product-in-context.md +56 -0
  73. package/kb/moves/real-world-data.md +58 -0
  74. package/kb/moves/referral-reward-reveal.md +59 -0
  75. package/kb/moves/riso-print-texture.md +57 -0
  76. package/kb/moves/screenshot-detail-crops.md +56 -0
  77. package/kb/moves/scroll-progress-chapters.md +57 -0
  78. package/kb/moves/scroll-scrubbed-product-film.md +62 -0
  79. package/kb/moves/self-playing-product-demo.md +61 -0
  80. package/kb/moves/shape-continuity-morph.md +58 -0
  81. package/kb/moves/sliding-nav-indicator.md +58 -0
  82. package/kb/moves/sticky-scroll-story.md +56 -0
  83. package/kb/moves/story-led-long-scroll.md +56 -0
  84. package/kb/moves/tactile-button.md +63 -0
  85. package/kb/moves/technical-drawing-lines.md +57 -0
  86. package/kb/moves/time-of-day-theming.md +56 -0
  87. package/kb/moves/tiny-game-easter-egg.md +60 -0
  88. package/kb/moves/type-decode-reveal.md +57 -0
  89. package/kb/moves/typographic-numeral-hero.md +58 -0
  90. package/kb/moves/view-transitions-between-pages.md +57 -0
  91. package/kb/moves/waitlist-position-live.md +60 -0
  92. package/kb/patterns/app-team-members.md +27 -0
  93. package/kb/patterns/chat-agent-approvals.md +31 -0
  94. package/kb/patterns/commerce-product-page.md +34 -0
  95. package/kb/patterns/dashboard-entity-table.md +37 -0
  96. package/kb/patterns/dashboard-home-today.md +24 -0
  97. package/kb/patterns/docs-api-reference.md +31 -0
  98. package/kb/patterns/marketing-product-led-landing.md +30 -0
  99. package/kb/patterns/mobile-daily-checklist.md +26 -0
  100. package/kb/references/index.json +1 -0
  101. package/kb/references/thumbs/004c5e9072.jpg +0 -0
  102. package/kb/references/thumbs/008915eb21.jpg +0 -0
  103. package/kb/references/thumbs/0098cf66c2.jpg +0 -0
  104. package/kb/references/thumbs/012e61b31f.jpg +0 -0
  105. package/kb/references/thumbs/014d4e46fc.jpg +0 -0
  106. package/kb/references/thumbs/01e54f394a.jpg +0 -0
  107. package/kb/references/thumbs/01e99a579c.jpg +0 -0
  108. package/kb/references/thumbs/01fd014575.jpg +0 -0
  109. package/kb/references/thumbs/022778ca72.jpg +0 -0
  110. package/kb/references/thumbs/02717bf1e1.jpg +0 -0
  111. package/kb/references/thumbs/02a5cfdbe9.jpg +0 -0
  112. package/kb/references/thumbs/02c9823f8d.jpg +0 -0
  113. package/kb/references/thumbs/02f3974613.jpg +0 -0
  114. package/kb/references/thumbs/032427f1ce.jpg +0 -0
  115. package/kb/references/thumbs/03ba677d07.jpg +0 -0
  116. package/kb/references/thumbs/04f2476cfe.jpg +0 -0
  117. package/kb/references/thumbs/0563e7c52e.jpg +0 -0
  118. package/kb/references/thumbs/05fa6b8eef.jpg +0 -0
  119. package/kb/references/thumbs/065bce1517.jpg +0 -0
  120. package/kb/references/thumbs/06c017f113.jpg +0 -0
  121. package/kb/references/thumbs/0770e2d8d3.jpg +0 -0
  122. package/kb/references/thumbs/078a26c4cb.jpg +0 -0
  123. package/kb/references/thumbs/08679b6e84.jpg +0 -0
  124. package/kb/references/thumbs/088c45a34c.jpg +0 -0
  125. package/kb/references/thumbs/089e9fd4e4.jpg +0 -0
  126. package/kb/references/thumbs/08f773231e.jpg +0 -0
  127. package/kb/references/thumbs/093ca3e2e3.jpg +0 -0
  128. package/kb/references/thumbs/0963320f74.jpg +0 -0
  129. package/kb/references/thumbs/09fc1ded85.jpg +0 -0
  130. package/kb/references/thumbs/0a368f3963.jpg +0 -0
  131. package/kb/references/thumbs/0a9e0e5201.jpg +0 -0
  132. package/kb/references/thumbs/0aace67ee7.jpg +0 -0
  133. package/kb/references/thumbs/0b61ecf793.jpg +0 -0
  134. package/kb/references/thumbs/0bde18ae09.jpg +0 -0
  135. package/kb/references/thumbs/0bf7ee8143.jpg +0 -0
  136. package/kb/references/thumbs/0ca20a13e0.jpg +0 -0
  137. package/kb/references/thumbs/0cdc0198c4.jpg +0 -0
  138. package/kb/references/thumbs/0cf9790b28.jpg +0 -0
  139. package/kb/references/thumbs/0d0202904b.jpg +0 -0
  140. package/kb/references/thumbs/0d053aba18.jpg +0 -0
  141. package/kb/references/thumbs/0d0c2c13d2.jpg +0 -0
  142. package/kb/references/thumbs/0d30be99b0.jpg +0 -0
  143. package/kb/references/thumbs/0d503da1b7.jpg +0 -0
  144. package/kb/references/thumbs/0ddad7b740.jpg +0 -0
  145. package/kb/references/thumbs/0e0a148101.jpg +0 -0
  146. package/kb/references/thumbs/0e401b6b75.jpg +0 -0
  147. package/kb/references/thumbs/0e8f32ba0f.jpg +0 -0
  148. package/kb/references/thumbs/0ef1966a7d.jpg +0 -0
  149. package/kb/references/thumbs/0efd416d11.jpg +0 -0
  150. package/kb/references/thumbs/0f3af263ae.jpg +0 -0
  151. package/kb/references/thumbs/0f9644c3a5.jpg +0 -0
  152. package/kb/references/thumbs/1020552737.jpg +0 -0
  153. package/kb/references/thumbs/1037626587.jpg +0 -0
  154. package/kb/references/thumbs/10512b7e94.jpg +0 -0
  155. package/kb/references/thumbs/106dc4a7b5.jpg +0 -0
  156. package/kb/references/thumbs/108943f6f7.jpg +0 -0
  157. package/kb/references/thumbs/10a5551d51.jpg +0 -0
  158. package/kb/references/thumbs/10dd01076c.jpg +0 -0
  159. package/kb/references/thumbs/11b06e39da.jpg +0 -0
  160. package/kb/references/thumbs/11baa1ec83.jpg +0 -0
  161. package/kb/references/thumbs/11bbe12167.jpg +0 -0
  162. package/kb/references/thumbs/11ca37feb8.jpg +0 -0
  163. package/kb/references/thumbs/11f14d3f12.jpg +0 -0
  164. package/kb/references/thumbs/124530ceb5.jpg +0 -0
  165. package/kb/references/thumbs/1276402336.jpg +0 -0
  166. package/kb/references/thumbs/1280e5c9d6.jpg +0 -0
  167. package/kb/references/thumbs/12cac0d172.jpg +0 -0
  168. package/kb/references/thumbs/138be6623a.jpg +0 -0
  169. package/kb/references/thumbs/13a0c544d1.jpg +0 -0
  170. package/kb/references/thumbs/13a32cb94c.jpg +0 -0
  171. package/kb/references/thumbs/144035d641.jpg +0 -0
  172. package/kb/references/thumbs/1457e41924.jpg +0 -0
  173. package/kb/references/thumbs/14972e3a86.jpg +0 -0
  174. package/kb/references/thumbs/15a47f2e4c.jpg +0 -0
  175. package/kb/references/thumbs/15aa15d22e.jpg +0 -0
  176. package/kb/references/thumbs/160dcd24b7.jpg +0 -0
  177. package/kb/references/thumbs/1610978529.jpg +0 -0
  178. package/kb/references/thumbs/16db30ba37.jpg +0 -0
  179. package/kb/references/thumbs/16f19ae4f3.jpg +0 -0
  180. package/kb/references/thumbs/16f758b03f.jpg +0 -0
  181. package/kb/references/thumbs/1748e5b751.jpg +0 -0
  182. package/kb/references/thumbs/175d0b0e69.jpg +0 -0
  183. package/kb/references/thumbs/178f571a36.jpg +0 -0
  184. package/kb/references/thumbs/17c43dc025.jpg +0 -0
  185. package/kb/references/thumbs/17c7f05b50.jpg +0 -0
  186. package/kb/references/thumbs/17f97e61dd.jpg +0 -0
  187. package/kb/references/thumbs/1804e17365.jpg +0 -0
  188. package/kb/references/thumbs/195c162ed1.jpg +0 -0
  189. package/kb/references/thumbs/19e3699c29.jpg +0 -0
  190. package/kb/references/thumbs/1a48e0a4d5.jpg +0 -0
  191. package/kb/references/thumbs/1a6cda265e.jpg +0 -0
  192. package/kb/references/thumbs/1a7e012091.jpg +0 -0
  193. package/kb/references/thumbs/1a9173a172.jpg +0 -0
  194. package/kb/references/thumbs/1b34a6b4d2.jpg +0 -0
  195. package/kb/references/thumbs/1b5284f3b2.jpg +0 -0
  196. package/kb/references/thumbs/1b93fbd6d3.jpg +0 -0
  197. package/kb/references/thumbs/1c6728fef6.jpg +0 -0
  198. package/kb/references/thumbs/1c6f101618.jpg +0 -0
  199. package/kb/references/thumbs/1cf7011a94.jpg +0 -0
  200. package/kb/references/thumbs/1d1769e539.jpg +0 -0
  201. package/kb/references/thumbs/1d1fd23199.jpg +0 -0
  202. package/kb/references/thumbs/1d7b6602ac.jpg +0 -0
  203. package/kb/references/thumbs/1dbbc61b9e.jpg +0 -0
  204. package/kb/references/thumbs/1dbdd6d21d.jpg +0 -0
  205. package/kb/references/thumbs/1dd873744b.jpg +0 -0
  206. package/kb/references/thumbs/1df4dd7cf9.jpg +0 -0
  207. package/kb/references/thumbs/1ece8c35b8.jpg +0 -0
  208. package/kb/references/thumbs/1f0e5b9aa4.jpg +0 -0
  209. package/kb/references/thumbs/1f1419651b.jpg +0 -0
  210. package/kb/references/thumbs/1f2a6da92d.jpg +0 -0
  211. package/kb/references/thumbs/1f651f33c0.jpg +0 -0
  212. package/kb/references/thumbs/1f8b697d18.jpg +0 -0
  213. package/kb/references/thumbs/1fee3824cd.jpg +0 -0
  214. package/kb/references/thumbs/1ff7757853.jpg +0 -0
  215. package/kb/references/thumbs/2043182f01.jpg +0 -0
  216. package/kb/references/thumbs/2059dabcd5.jpg +0 -0
  217. package/kb/references/thumbs/209d9dbb95.jpg +0 -0
  218. package/kb/references/thumbs/20d8923554.jpg +0 -0
  219. package/kb/references/thumbs/210dd3b671.jpg +0 -0
  220. package/kb/references/thumbs/2120719116.jpg +0 -0
  221. package/kb/references/thumbs/21a7384429.jpg +0 -0
  222. package/kb/references/thumbs/225f187391.jpg +0 -0
  223. package/kb/references/thumbs/230caf7dd2.jpg +0 -0
  224. package/kb/references/thumbs/235afad355.jpg +0 -0
  225. package/kb/references/thumbs/2378066687.jpg +0 -0
  226. package/kb/references/thumbs/241faf68a1.jpg +0 -0
  227. package/kb/references/thumbs/24d9f1a9b9.jpg +0 -0
  228. package/kb/references/thumbs/2505c8b9a0.jpg +0 -0
  229. package/kb/references/thumbs/25593638ca.jpg +0 -0
  230. package/kb/references/thumbs/25dd454f18.jpg +0 -0
  231. package/kb/references/thumbs/2602e123e2.jpg +0 -0
  232. package/kb/references/thumbs/26095c0b11.jpg +0 -0
  233. package/kb/references/thumbs/26260d6238.jpg +0 -0
  234. package/kb/references/thumbs/26bba21836.jpg +0 -0
  235. package/kb/references/thumbs/26bde3520b.jpg +0 -0
  236. package/kb/references/thumbs/272e22067c.jpg +0 -0
  237. package/kb/references/thumbs/27421b3226.jpg +0 -0
  238. package/kb/references/thumbs/2769ebca41.jpg +0 -0
  239. package/kb/references/thumbs/27e2f6e8b0.jpg +0 -0
  240. package/kb/references/thumbs/28432ba373.jpg +0 -0
  241. package/kb/references/thumbs/2846626f19.jpg +0 -0
  242. package/kb/references/thumbs/28750e821e.jpg +0 -0
  243. package/kb/references/thumbs/289481230f.jpg +0 -0
  244. package/kb/references/thumbs/2897967408.jpg +0 -0
  245. package/kb/references/thumbs/28c0a5fa17.jpg +0 -0
  246. package/kb/references/thumbs/28c181fba5.jpg +0 -0
  247. package/kb/references/thumbs/29806f539f.jpg +0 -0
  248. package/kb/references/thumbs/2997f56ee7.jpg +0 -0
  249. package/kb/references/thumbs/29b34a10fb.jpg +0 -0
  250. package/kb/references/thumbs/29bd78cdb4.jpg +0 -0
  251. package/kb/references/thumbs/29c8c6c22a.jpg +0 -0
  252. package/kb/references/thumbs/2ac23f7fae.jpg +0 -0
  253. package/kb/references/thumbs/2b76e13f79.jpg +0 -0
  254. package/kb/references/thumbs/2b84226479.jpg +0 -0
  255. package/kb/references/thumbs/2bf2dbf737.jpg +0 -0
  256. package/kb/references/thumbs/2bf89abbf6.jpg +0 -0
  257. package/kb/references/thumbs/2c562cd534.jpg +0 -0
  258. package/kb/references/thumbs/2cfe9d48c4.jpg +0 -0
  259. package/kb/references/thumbs/2d49f19b27.jpg +0 -0
  260. package/kb/references/thumbs/2dc8670da7.jpg +0 -0
  261. package/kb/references/thumbs/2de947c469.jpg +0 -0
  262. package/kb/references/thumbs/2e075ca79f.jpg +0 -0
  263. package/kb/references/thumbs/2eb0820e6b.jpg +0 -0
  264. package/kb/references/thumbs/2ec56a9dc0.jpg +0 -0
  265. package/kb/references/thumbs/30bb4ad607.jpg +0 -0
  266. package/kb/references/thumbs/30d19b8444.jpg +0 -0
  267. package/kb/references/thumbs/3173c71d73.jpg +0 -0
  268. package/kb/references/thumbs/31e59e4518.jpg +0 -0
  269. package/kb/references/thumbs/322b8960e8.jpg +0 -0
  270. package/kb/references/thumbs/325c9be6f4.jpg +0 -0
  271. package/kb/references/thumbs/3273338982.jpg +0 -0
  272. package/kb/references/thumbs/32f8387f38.jpg +0 -0
  273. package/kb/references/thumbs/332f6b74c3.jpg +0 -0
  274. package/kb/references/thumbs/334b146b6a.jpg +0 -0
  275. package/kb/references/thumbs/339abd60e4.jpg +0 -0
  276. package/kb/references/thumbs/33e88ec295.jpg +0 -0
  277. package/kb/references/thumbs/340931b5d4.jpg +0 -0
  278. package/kb/references/thumbs/34165a93bd.jpg +0 -0
  279. package/kb/references/thumbs/34d0575dd7.jpg +0 -0
  280. package/kb/references/thumbs/3549e75f0a.jpg +0 -0
  281. package/kb/references/thumbs/35827f1561.jpg +0 -0
  282. package/kb/references/thumbs/37c50280ec.jpg +0 -0
  283. package/kb/references/thumbs/37e66ecf11.jpg +0 -0
  284. package/kb/references/thumbs/3841a04fdc.jpg +0 -0
  285. package/kb/references/thumbs/38490c088f.jpg +0 -0
  286. package/kb/references/thumbs/3850319e9f.jpg +0 -0
  287. package/kb/references/thumbs/3856a64166.jpg +0 -0
  288. package/kb/references/thumbs/3881f211c2.jpg +0 -0
  289. package/kb/references/thumbs/38c7dde2f3.jpg +0 -0
  290. package/kb/references/thumbs/38ce9e486c.jpg +0 -0
  291. package/kb/references/thumbs/390ea8e01b.jpg +0 -0
  292. package/kb/references/thumbs/391b7fc27c.jpg +0 -0
  293. package/kb/references/thumbs/395f7214dc.jpg +0 -0
  294. package/kb/references/thumbs/39e81a5db2.jpg +0 -0
  295. package/kb/references/thumbs/3a67c8d655.jpg +0 -0
  296. package/kb/references/thumbs/3a89c25e3b.jpg +0 -0
  297. package/kb/references/thumbs/3aa0837542.jpg +0 -0
  298. package/kb/references/thumbs/3aae18aa8a.jpg +0 -0
  299. package/kb/references/thumbs/3bdbe767db.jpg +0 -0
  300. package/kb/references/thumbs/3c0616fc7f.jpg +0 -0
  301. package/kb/references/thumbs/3c18e9db1d.jpg +0 -0
  302. package/kb/references/thumbs/3c5a14076c.jpg +0 -0
  303. package/kb/references/thumbs/3ca9ec15c6.jpg +0 -0
  304. package/kb/references/thumbs/3d7756fd35.jpg +0 -0
  305. package/kb/references/thumbs/3dd45bd33d.jpg +0 -0
  306. package/kb/references/thumbs/3de72d5414.jpg +0 -0
  307. package/kb/references/thumbs/3dede597af.jpg +0 -0
  308. package/kb/references/thumbs/3ea948619e.jpg +0 -0
  309. package/kb/references/thumbs/402c12054c.jpg +0 -0
  310. package/kb/references/thumbs/403ab4af90.jpg +0 -0
  311. package/kb/references/thumbs/40773a8c63.jpg +0 -0
  312. package/kb/references/thumbs/407d9583db.jpg +0 -0
  313. package/kb/references/thumbs/415dc1d84c.jpg +0 -0
  314. package/kb/references/thumbs/420b676a4f.jpg +0 -0
  315. package/kb/references/thumbs/42a1ee85eb.jpg +0 -0
  316. package/kb/references/thumbs/43059221aa.jpg +0 -0
  317. package/kb/references/thumbs/432fa0d22c.jpg +0 -0
  318. package/kb/references/thumbs/43826f20e3.jpg +0 -0
  319. package/kb/references/thumbs/43ac55c98a.jpg +0 -0
  320. package/kb/references/thumbs/43d098f3c3.jpg +0 -0
  321. package/kb/references/thumbs/4449d80c2c.jpg +0 -0
  322. package/kb/references/thumbs/44625727dc.jpg +0 -0
  323. package/kb/references/thumbs/4482bb87a1.jpg +0 -0
  324. package/kb/references/thumbs/44b078acdc.jpg +0 -0
  325. package/kb/references/thumbs/44d0305850.jpg +0 -0
  326. package/kb/references/thumbs/456bb6b59e.jpg +0 -0
  327. package/kb/references/thumbs/45df73ce48.jpg +0 -0
  328. package/kb/references/thumbs/45edb45d87.jpg +0 -0
  329. package/kb/references/thumbs/4671d57cd5.jpg +0 -0
  330. package/kb/references/thumbs/46cc108518.jpg +0 -0
  331. package/kb/references/thumbs/470022e614.jpg +0 -0
  332. package/kb/references/thumbs/4719a669ce.jpg +0 -0
  333. package/kb/references/thumbs/47404f5ad4.jpg +0 -0
  334. package/kb/references/thumbs/479d3eb977.jpg +0 -0
  335. package/kb/references/thumbs/479ed92ceb.jpg +0 -0
  336. package/kb/references/thumbs/47baed50c7.jpg +0 -0
  337. package/kb/references/thumbs/47fdcfd7b0.jpg +0 -0
  338. package/kb/references/thumbs/48fd5e94c5.jpg +0 -0
  339. package/kb/references/thumbs/493807917b.jpg +0 -0
  340. package/kb/references/thumbs/49a1c67293.jpg +0 -0
  341. package/kb/references/thumbs/49e2d7fafe.jpg +0 -0
  342. package/kb/references/thumbs/49f540fcb6.jpg +0 -0
  343. package/kb/references/thumbs/4a67ec4028.jpg +0 -0
  344. package/kb/references/thumbs/4a93275b04.jpg +0 -0
  345. package/kb/references/thumbs/4aae6f52da.jpg +0 -0
  346. package/kb/references/thumbs/4b1bae66bd.jpg +0 -0
  347. package/kb/references/thumbs/4b75da15a9.jpg +0 -0
  348. package/kb/references/thumbs/4b77789b88.jpg +0 -0
  349. package/kb/references/thumbs/4bc2f3f3a4.jpg +0 -0
  350. package/kb/references/thumbs/4c48f27b88.jpg +0 -0
  351. package/kb/references/thumbs/4c52bd8bfb.jpg +0 -0
  352. package/kb/references/thumbs/4c9b4acc60.jpg +0 -0
  353. package/kb/references/thumbs/4cbf0752d4.jpg +0 -0
  354. package/kb/references/thumbs/4cd2672517.jpg +0 -0
  355. package/kb/references/thumbs/4dd22a8181.jpg +0 -0
  356. package/kb/references/thumbs/4ee3447314.jpg +0 -0
  357. package/kb/references/thumbs/4ef29c8144.jpg +0 -0
  358. package/kb/references/thumbs/4f82fadfd6.jpg +0 -0
  359. package/kb/references/thumbs/4fc9b643d8.jpg +0 -0
  360. package/kb/references/thumbs/50549524b0.jpg +0 -0
  361. package/kb/references/thumbs/509a615883.jpg +0 -0
  362. package/kb/references/thumbs/50c03ef855.jpg +0 -0
  363. package/kb/references/thumbs/50cf9acad6.jpg +0 -0
  364. package/kb/references/thumbs/51131b025c.jpg +0 -0
  365. package/kb/references/thumbs/51da1124f0.jpg +0 -0
  366. package/kb/references/thumbs/524d5e7288.jpg +0 -0
  367. package/kb/references/thumbs/5251247c81.jpg +0 -0
  368. package/kb/references/thumbs/526b91b7ec.jpg +0 -0
  369. package/kb/references/thumbs/52f02f6c2e.jpg +0 -0
  370. package/kb/references/thumbs/530ab530dc.jpg +0 -0
  371. package/kb/references/thumbs/5335ee4404.jpg +0 -0
  372. package/kb/references/thumbs/5385b90939.jpg +0 -0
  373. package/kb/references/thumbs/53c54654cc.jpg +0 -0
  374. package/kb/references/thumbs/5420794c6c.jpg +0 -0
  375. package/kb/references/thumbs/542a9dce8b.jpg +0 -0
  376. package/kb/references/thumbs/5571530a5f.jpg +0 -0
  377. package/kb/references/thumbs/56cc68d804.jpg +0 -0
  378. package/kb/references/thumbs/577b7f7c44.jpg +0 -0
  379. package/kb/references/thumbs/57adf8f1bb.jpg +0 -0
  380. package/kb/references/thumbs/57c5f5e3a6.jpg +0 -0
  381. package/kb/references/thumbs/57ffe4e839.jpg +0 -0
  382. package/kb/references/thumbs/5817dfc7d6.jpg +0 -0
  383. package/kb/references/thumbs/581a182a7a.jpg +0 -0
  384. package/kb/references/thumbs/58807679c8.jpg +0 -0
  385. package/kb/references/thumbs/589a1d9111.jpg +0 -0
  386. package/kb/references/thumbs/59167391ab.jpg +0 -0
  387. package/kb/references/thumbs/5a70420166.jpg +0 -0
  388. package/kb/references/thumbs/5b10df1b8d.jpg +0 -0
  389. package/kb/references/thumbs/5b7a712fdb.jpg +0 -0
  390. package/kb/references/thumbs/5bc46b92ad.jpg +0 -0
  391. package/kb/references/thumbs/5c0546a120.jpg +0 -0
  392. package/kb/references/thumbs/5c2b6125a8.jpg +0 -0
  393. package/kb/references/thumbs/5c536b9e42.jpg +0 -0
  394. package/kb/references/thumbs/5c8e441d30.jpg +0 -0
  395. package/kb/references/thumbs/5cb6f1baa5.jpg +0 -0
  396. package/kb/references/thumbs/5ce6c1f21e.jpg +0 -0
  397. package/kb/references/thumbs/5cef052c0a.jpg +0 -0
  398. package/kb/references/thumbs/5d08438209.jpg +0 -0
  399. package/kb/references/thumbs/5d0f9af9b0.jpg +0 -0
  400. package/kb/references/thumbs/5d300ed332.jpg +0 -0
  401. package/kb/references/thumbs/5d708a4794.jpg +0 -0
  402. package/kb/references/thumbs/5de8826a98.jpg +0 -0
  403. package/kb/references/thumbs/5df7bff22c.jpg +0 -0
  404. package/kb/references/thumbs/5e087d0f00.jpg +0 -0
  405. package/kb/references/thumbs/5e44e70ca0.jpg +0 -0
  406. package/kb/references/thumbs/5eff5d80ce.jpg +0 -0
  407. package/kb/references/thumbs/5f015c96b1.jpg +0 -0
  408. package/kb/references/thumbs/5f3289b7c4.jpg +0 -0
  409. package/kb/references/thumbs/5f830c40eb.jpg +0 -0
  410. package/kb/references/thumbs/60c4c3527b.jpg +0 -0
  411. package/kb/references/thumbs/60e9e594dd.jpg +0 -0
  412. package/kb/references/thumbs/615421d7be.jpg +0 -0
  413. package/kb/references/thumbs/6176e4004f.jpg +0 -0
  414. package/kb/references/thumbs/61f0fe5e06.jpg +0 -0
  415. package/kb/references/thumbs/6213785db4.jpg +0 -0
  416. package/kb/references/thumbs/62a670ae09.jpg +0 -0
  417. package/kb/references/thumbs/63cc12981b.jpg +0 -0
  418. package/kb/references/thumbs/641f15cc71.jpg +0 -0
  419. package/kb/references/thumbs/642ab2081d.jpg +0 -0
  420. package/kb/references/thumbs/644a59bf6e.jpg +0 -0
  421. package/kb/references/thumbs/644da8a8e3.jpg +0 -0
  422. package/kb/references/thumbs/6458986897.jpg +0 -0
  423. package/kb/references/thumbs/64cfbd7b93.jpg +0 -0
  424. package/kb/references/thumbs/661a57686a.jpg +0 -0
  425. package/kb/references/thumbs/66355a813a.jpg +0 -0
  426. package/kb/references/thumbs/664396dd44.jpg +0 -0
  427. package/kb/references/thumbs/66d832d65f.jpg +0 -0
  428. package/kb/references/thumbs/66de9e9833.jpg +0 -0
  429. package/kb/references/thumbs/6750964fd9.jpg +0 -0
  430. package/kb/references/thumbs/67c7164832.jpg +0 -0
  431. package/kb/references/thumbs/681600b6cd.jpg +0 -0
  432. package/kb/references/thumbs/682e75afe4.jpg +0 -0
  433. package/kb/references/thumbs/69274bc952.jpg +0 -0
  434. package/kb/references/thumbs/696ec08c52.jpg +0 -0
  435. package/kb/references/thumbs/69760111cc.jpg +0 -0
  436. package/kb/references/thumbs/697e32664f.jpg +0 -0
  437. package/kb/references/thumbs/69df92544b.jpg +0 -0
  438. package/kb/references/thumbs/69e48c5229.jpg +0 -0
  439. package/kb/references/thumbs/6a5fb75de1.jpg +0 -0
  440. package/kb/references/thumbs/6a7389e472.jpg +0 -0
  441. package/kb/references/thumbs/6a9b041e02.jpg +0 -0
  442. package/kb/references/thumbs/6ab2fa93ee.jpg +0 -0
  443. package/kb/references/thumbs/6ae3400319.jpg +0 -0
  444. package/kb/references/thumbs/6b21344bf3.jpg +0 -0
  445. package/kb/references/thumbs/6bd1b67a8a.jpg +0 -0
  446. package/kb/references/thumbs/6c99156c4f.jpg +0 -0
  447. package/kb/references/thumbs/6cc9b65384.jpg +0 -0
  448. package/kb/references/thumbs/6d15830a73.jpg +0 -0
  449. package/kb/references/thumbs/6d4c33d180.jpg +0 -0
  450. package/kb/references/thumbs/6e36815799.jpg +0 -0
  451. package/kb/references/thumbs/6eddb9cbfc.jpg +0 -0
  452. package/kb/references/thumbs/6f97968a7c.jpg +0 -0
  453. package/kb/references/thumbs/6fa0716a7d.jpg +0 -0
  454. package/kb/references/thumbs/6facd57184.jpg +0 -0
  455. package/kb/references/thumbs/6fd57b785a.jpg +0 -0
  456. package/kb/references/thumbs/700b3cb185.jpg +0 -0
  457. package/kb/references/thumbs/71197443fa.jpg +0 -0
  458. package/kb/references/thumbs/72082bc9ee.jpg +0 -0
  459. package/kb/references/thumbs/72453db479.jpg +0 -0
  460. package/kb/references/thumbs/72cd64d500.jpg +0 -0
  461. package/kb/references/thumbs/72d1e75283.jpg +0 -0
  462. package/kb/references/thumbs/72e13f7f5b.jpg +0 -0
  463. package/kb/references/thumbs/7459f8e644.jpg +0 -0
  464. package/kb/references/thumbs/7470d55c79.jpg +0 -0
  465. package/kb/references/thumbs/74c468f02a.jpg +0 -0
  466. package/kb/references/thumbs/74fed6eb77.jpg +0 -0
  467. package/kb/references/thumbs/756e05080d.jpg +0 -0
  468. package/kb/references/thumbs/75df7e5f49.jpg +0 -0
  469. package/kb/references/thumbs/76226da6ef.jpg +0 -0
  470. package/kb/references/thumbs/76a34aa056.jpg +0 -0
  471. package/kb/references/thumbs/76c7076589.jpg +0 -0
  472. package/kb/references/thumbs/76cccc396c.jpg +0 -0
  473. package/kb/references/thumbs/774654789f.jpg +0 -0
  474. package/kb/references/thumbs/7746cc494d.jpg +0 -0
  475. package/kb/references/thumbs/7766e36aa3.jpg +0 -0
  476. package/kb/references/thumbs/78049331ef.jpg +0 -0
  477. package/kb/references/thumbs/78808a0ca5.jpg +0 -0
  478. package/kb/references/thumbs/7890b0a310.jpg +0 -0
  479. package/kb/references/thumbs/78911975e6.jpg +0 -0
  480. package/kb/references/thumbs/78d289d5a0.jpg +0 -0
  481. package/kb/references/thumbs/794126267e.jpg +0 -0
  482. package/kb/references/thumbs/7976eb9025.jpg +0 -0
  483. package/kb/references/thumbs/798519ec7c.jpg +0 -0
  484. package/kb/references/thumbs/7a6cc5eecc.jpg +0 -0
  485. package/kb/references/thumbs/7ac8a7cd4a.jpg +0 -0
  486. package/kb/references/thumbs/7b1341d61d.jpg +0 -0
  487. package/kb/references/thumbs/7b9c4031e3.jpg +0 -0
  488. package/kb/references/thumbs/7ba5ad3779.jpg +0 -0
  489. package/kb/references/thumbs/7be6eb2bd0.jpg +0 -0
  490. package/kb/references/thumbs/7c30864f5d.jpg +0 -0
  491. package/kb/references/thumbs/7c379b5e17.jpg +0 -0
  492. package/kb/references/thumbs/7c4050eb02.jpg +0 -0
  493. package/kb/references/thumbs/7ca47b3221.jpg +0 -0
  494. package/kb/references/thumbs/7d43516bd7.jpg +0 -0
  495. package/kb/references/thumbs/7da9dbb98a.jpg +0 -0
  496. package/kb/references/thumbs/7ddda8f57c.jpg +0 -0
  497. package/kb/references/thumbs/7ece6d215c.jpg +0 -0
  498. package/kb/references/thumbs/7eebf029de.jpg +0 -0
  499. package/kb/references/thumbs/7f45483c15.jpg +0 -0
  500. package/kb/references/thumbs/7fde06eaa5.jpg +0 -0
  501. package/kb/references/thumbs/80407b97e9.jpg +0 -0
  502. package/kb/references/thumbs/80f0a6cf4b.jpg +0 -0
  503. package/kb/references/thumbs/8118b451b8.jpg +0 -0
  504. package/kb/references/thumbs/816baed4a8.jpg +0 -0
  505. package/kb/references/thumbs/817d2d15d9.jpg +0 -0
  506. package/kb/references/thumbs/8260cb430d.jpg +0 -0
  507. package/kb/references/thumbs/827b562899.jpg +0 -0
  508. package/kb/references/thumbs/8293cf1e92.jpg +0 -0
  509. package/kb/references/thumbs/8294653169.jpg +0 -0
  510. package/kb/references/thumbs/83061f871f.jpg +0 -0
  511. package/kb/references/thumbs/833df778ca.jpg +0 -0
  512. package/kb/references/thumbs/83d3acaafc.jpg +0 -0
  513. package/kb/references/thumbs/844c6efeff.jpg +0 -0
  514. package/kb/references/thumbs/84563d482a.jpg +0 -0
  515. package/kb/references/thumbs/848082dd94.jpg +0 -0
  516. package/kb/references/thumbs/8494b1da94.jpg +0 -0
  517. package/kb/references/thumbs/84b71014be.jpg +0 -0
  518. package/kb/references/thumbs/84be4a5f3c.jpg +0 -0
  519. package/kb/references/thumbs/84fd0fd25a.jpg +0 -0
  520. package/kb/references/thumbs/853e488e22.jpg +0 -0
  521. package/kb/references/thumbs/858c91585d.jpg +0 -0
  522. package/kb/references/thumbs/85903e8fe9.jpg +0 -0
  523. package/kb/references/thumbs/86597d43fd.jpg +0 -0
  524. package/kb/references/thumbs/866eb99500.jpg +0 -0
  525. package/kb/references/thumbs/86ac050340.jpg +0 -0
  526. package/kb/references/thumbs/86afec7b64.jpg +0 -0
  527. package/kb/references/thumbs/87238127f5.jpg +0 -0
  528. package/kb/references/thumbs/87321df792.jpg +0 -0
  529. package/kb/references/thumbs/87460f70cd.jpg +0 -0
  530. package/kb/references/thumbs/8770dfeaec.jpg +0 -0
  531. package/kb/references/thumbs/8798451a8c.jpg +0 -0
  532. package/kb/references/thumbs/87da1f34a3.jpg +0 -0
  533. package/kb/references/thumbs/882cdf8c05.jpg +0 -0
  534. package/kb/references/thumbs/8839f4106f.jpg +0 -0
  535. package/kb/references/thumbs/8844455212.jpg +0 -0
  536. package/kb/references/thumbs/88abba0497.jpg +0 -0
  537. package/kb/references/thumbs/88b372435d.jpg +0 -0
  538. package/kb/references/thumbs/88bd4f35fa.jpg +0 -0
  539. package/kb/references/thumbs/88c71a075e.jpg +0 -0
  540. package/kb/references/thumbs/892e5f048e.jpg +0 -0
  541. package/kb/references/thumbs/893cc8e920.jpg +0 -0
  542. package/kb/references/thumbs/896c198814.jpg +0 -0
  543. package/kb/references/thumbs/8a8e22f756.jpg +0 -0
  544. package/kb/references/thumbs/8a9d8a35cb.jpg +0 -0
  545. package/kb/references/thumbs/8ab1d67fec.jpg +0 -0
  546. package/kb/references/thumbs/8ab201fe12.jpg +0 -0
  547. package/kb/references/thumbs/8ac372c102.jpg +0 -0
  548. package/kb/references/thumbs/8b15736d62.jpg +0 -0
  549. package/kb/references/thumbs/8b1d8d6a05.jpg +0 -0
  550. package/kb/references/thumbs/8bb6050e20.jpg +0 -0
  551. package/kb/references/thumbs/8c6c9d1577.jpg +0 -0
  552. package/kb/references/thumbs/8d337851e0.jpg +0 -0
  553. package/kb/references/thumbs/8d44b33cc5.jpg +0 -0
  554. package/kb/references/thumbs/8d4536ff3b.jpg +0 -0
  555. package/kb/references/thumbs/8d9b99454a.jpg +0 -0
  556. package/kb/references/thumbs/8dda2303ff.jpg +0 -0
  557. package/kb/references/thumbs/8dec722d62.jpg +0 -0
  558. package/kb/references/thumbs/8e0ea4ca74.jpg +0 -0
  559. package/kb/references/thumbs/8ebba84d69.jpg +0 -0
  560. package/kb/references/thumbs/8ef09140c0.jpg +0 -0
  561. package/kb/references/thumbs/8f2928a1b0.jpg +0 -0
  562. package/kb/references/thumbs/8f88f9ddba.jpg +0 -0
  563. package/kb/references/thumbs/8fa4451009.jpg +0 -0
  564. package/kb/references/thumbs/90109b0e02.jpg +0 -0
  565. package/kb/references/thumbs/90e854e5c9.jpg +0 -0
  566. package/kb/references/thumbs/914e79f893.jpg +0 -0
  567. package/kb/references/thumbs/9161369197.jpg +0 -0
  568. package/kb/references/thumbs/9165c87d6f.jpg +0 -0
  569. package/kb/references/thumbs/9193f6558a.jpg +0 -0
  570. package/kb/references/thumbs/91ac7df877.jpg +0 -0
  571. package/kb/references/thumbs/9216bd4931.jpg +0 -0
  572. package/kb/references/thumbs/922ae8a26a.jpg +0 -0
  573. package/kb/references/thumbs/92a70e6867.jpg +0 -0
  574. package/kb/references/thumbs/92c77ece22.jpg +0 -0
  575. package/kb/references/thumbs/92e5914fbf.jpg +0 -0
  576. package/kb/references/thumbs/92ee36419a.jpg +0 -0
  577. package/kb/references/thumbs/94153a60b0.jpg +0 -0
  578. package/kb/references/thumbs/9449666640.jpg +0 -0
  579. package/kb/references/thumbs/944be6a646.jpg +0 -0
  580. package/kb/references/thumbs/945831476e.jpg +0 -0
  581. package/kb/references/thumbs/94c1af82f4.jpg +0 -0
  582. package/kb/references/thumbs/9599d6d589.jpg +0 -0
  583. package/kb/references/thumbs/960710f4cf.jpg +0 -0
  584. package/kb/references/thumbs/9608f12d64.jpg +0 -0
  585. package/kb/references/thumbs/962dabfaa0.jpg +0 -0
  586. package/kb/references/thumbs/965a3a95c6.jpg +0 -0
  587. package/kb/references/thumbs/9672ed5ae4.jpg +0 -0
  588. package/kb/references/thumbs/96891ae9c1.jpg +0 -0
  589. package/kb/references/thumbs/96e1907c99.jpg +0 -0
  590. package/kb/references/thumbs/96f25b6578.jpg +0 -0
  591. package/kb/references/thumbs/97211df9ae.jpg +0 -0
  592. package/kb/references/thumbs/9769d763a5.jpg +0 -0
  593. package/kb/references/thumbs/9792bd6d05.jpg +0 -0
  594. package/kb/references/thumbs/97d2837e3e.jpg +0 -0
  595. package/kb/references/thumbs/97d90d1d85.jpg +0 -0
  596. package/kb/references/thumbs/97fcd5774a.jpg +0 -0
  597. package/kb/references/thumbs/980f68564e.jpg +0 -0
  598. package/kb/references/thumbs/98511fb393.jpg +0 -0
  599. package/kb/references/thumbs/98f8fa694d.jpg +0 -0
  600. package/kb/references/thumbs/9a42c6bb97.jpg +0 -0
  601. package/kb/references/thumbs/9ab3600a06.jpg +0 -0
  602. package/kb/references/thumbs/9ab48d9130.jpg +0 -0
  603. package/kb/references/thumbs/9ad519197d.jpg +0 -0
  604. package/kb/references/thumbs/9b1382c657.jpg +0 -0
  605. package/kb/references/thumbs/9b6cc1e077.jpg +0 -0
  606. package/kb/references/thumbs/9beede8480.jpg +0 -0
  607. package/kb/references/thumbs/9bf8976952.jpg +0 -0
  608. package/kb/references/thumbs/9cace7b75a.jpg +0 -0
  609. package/kb/references/thumbs/9cdcc5745e.jpg +0 -0
  610. package/kb/references/thumbs/9d0b269074.jpg +0 -0
  611. package/kb/references/thumbs/9d41788b48.jpg +0 -0
  612. package/kb/references/thumbs/9d475bd6af.jpg +0 -0
  613. package/kb/references/thumbs/9e6bc543d0.jpg +0 -0
  614. package/kb/references/thumbs/9ed0e0a206.jpg +0 -0
  615. package/kb/references/thumbs/9ef538de13.jpg +0 -0
  616. package/kb/references/thumbs/9efc373ab4.jpg +0 -0
  617. package/kb/references/thumbs/9f4a939fa5.jpg +0 -0
  618. package/kb/references/thumbs/9f8d12d7b9.jpg +0 -0
  619. package/kb/references/thumbs/9fd5e3efa7.jpg +0 -0
  620. package/kb/references/thumbs/a0a9b9c572.jpg +0 -0
  621. package/kb/references/thumbs/a29ca9b185.jpg +0 -0
  622. package/kb/references/thumbs/a2a42884af.jpg +0 -0
  623. package/kb/references/thumbs/a2f5064e34.jpg +0 -0
  624. package/kb/references/thumbs/a3112ce672.jpg +0 -0
  625. package/kb/references/thumbs/a3437736d1.jpg +0 -0
  626. package/kb/references/thumbs/a372667e76.jpg +0 -0
  627. package/kb/references/thumbs/a39bae94e9.jpg +0 -0
  628. package/kb/references/thumbs/a3fc75d94c.jpg +0 -0
  629. package/kb/references/thumbs/a440487631.jpg +0 -0
  630. package/kb/references/thumbs/a4993d5fb5.jpg +0 -0
  631. package/kb/references/thumbs/a500476a86.jpg +0 -0
  632. package/kb/references/thumbs/a55506bf46.jpg +0 -0
  633. package/kb/references/thumbs/a59a5f9843.jpg +0 -0
  634. package/kb/references/thumbs/a5bce0eede.jpg +0 -0
  635. package/kb/references/thumbs/a5d921e1f0.jpg +0 -0
  636. package/kb/references/thumbs/a5e19d4637.jpg +0 -0
  637. package/kb/references/thumbs/a5f92b97d5.jpg +0 -0
  638. package/kb/references/thumbs/a6562c210a.jpg +0 -0
  639. package/kb/references/thumbs/a6f61a8d09.jpg +0 -0
  640. package/kb/references/thumbs/a719fdf663.jpg +0 -0
  641. package/kb/references/thumbs/a724e5442f.jpg +0 -0
  642. package/kb/references/thumbs/a852b4319f.jpg +0 -0
  643. package/kb/references/thumbs/a896c08448.jpg +0 -0
  644. package/kb/references/thumbs/a8d190a4b8.jpg +0 -0
  645. package/kb/references/thumbs/a8dcdd57d7.jpg +0 -0
  646. package/kb/references/thumbs/a951347e18.jpg +0 -0
  647. package/kb/references/thumbs/a9a1a0bf7d.jpg +0 -0
  648. package/kb/references/thumbs/a9b72986a8.jpg +0 -0
  649. package/kb/references/thumbs/aa11555ba8.jpg +0 -0
  650. package/kb/references/thumbs/aa4aab9093.jpg +0 -0
  651. package/kb/references/thumbs/aa89b96658.jpg +0 -0
  652. package/kb/references/thumbs/aaeb3739b6.jpg +0 -0
  653. package/kb/references/thumbs/ab25a608ec.jpg +0 -0
  654. package/kb/references/thumbs/ab34b62268.jpg +0 -0
  655. package/kb/references/thumbs/ab3b0217bb.jpg +0 -0
  656. package/kb/references/thumbs/ac70c04afb.jpg +0 -0
  657. package/kb/references/thumbs/ace0879117.jpg +0 -0
  658. package/kb/references/thumbs/ad0515ae55.jpg +0 -0
  659. package/kb/references/thumbs/ad66b25b47.jpg +0 -0
  660. package/kb/references/thumbs/ad68229d2f.jpg +0 -0
  661. package/kb/references/thumbs/add6480693.jpg +0 -0
  662. package/kb/references/thumbs/ae5b8c3b8c.jpg +0 -0
  663. package/kb/references/thumbs/ae81247b47.jpg +0 -0
  664. package/kb/references/thumbs/af8aa54379.jpg +0 -0
  665. package/kb/references/thumbs/afa80dedd4.jpg +0 -0
  666. package/kb/references/thumbs/afe04d730f.jpg +0 -0
  667. package/kb/references/thumbs/b09a7dc315.jpg +0 -0
  668. package/kb/references/thumbs/b0c02629f6.jpg +0 -0
  669. package/kb/references/thumbs/b1cb4f91de.jpg +0 -0
  670. package/kb/references/thumbs/b1d4c13c92.jpg +0 -0
  671. package/kb/references/thumbs/b20eef86db.jpg +0 -0
  672. package/kb/references/thumbs/b3136ccdde.jpg +0 -0
  673. package/kb/references/thumbs/b3f5e8d7dd.jpg +0 -0
  674. package/kb/references/thumbs/b44adb81c9.jpg +0 -0
  675. package/kb/references/thumbs/b457a5894b.jpg +0 -0
  676. package/kb/references/thumbs/b461281e0f.jpg +0 -0
  677. package/kb/references/thumbs/b4942644f0.jpg +0 -0
  678. package/kb/references/thumbs/b49f8eccad.jpg +0 -0
  679. package/kb/references/thumbs/b56c69be23.jpg +0 -0
  680. package/kb/references/thumbs/b59786b33c.jpg +0 -0
  681. package/kb/references/thumbs/b5d368ce5a.jpg +0 -0
  682. package/kb/references/thumbs/b5eb442406.jpg +0 -0
  683. package/kb/references/thumbs/b7fdabf4ab.jpg +0 -0
  684. package/kb/references/thumbs/b88ee8d235.jpg +0 -0
  685. package/kb/references/thumbs/b8a4e5be8a.jpg +0 -0
  686. package/kb/references/thumbs/b8c85b661c.jpg +0 -0
  687. package/kb/references/thumbs/ba1b8e7435.jpg +0 -0
  688. package/kb/references/thumbs/ba9a593eed.jpg +0 -0
  689. package/kb/references/thumbs/baa7afc201.jpg +0 -0
  690. package/kb/references/thumbs/baf74398f7.jpg +0 -0
  691. package/kb/references/thumbs/bb3e947c10.jpg +0 -0
  692. package/kb/references/thumbs/bb4c1bb7c1.jpg +0 -0
  693. package/kb/references/thumbs/bbaa25cc8a.jpg +0 -0
  694. package/kb/references/thumbs/bc7e7f88cc.jpg +0 -0
  695. package/kb/references/thumbs/bc9d5b58f5.jpg +0 -0
  696. package/kb/references/thumbs/bcc99a51f7.jpg +0 -0
  697. package/kb/references/thumbs/bce13dd1c1.jpg +0 -0
  698. package/kb/references/thumbs/bd079a6130.jpg +0 -0
  699. package/kb/references/thumbs/bd2d70dda7.jpg +0 -0
  700. package/kb/references/thumbs/bd5895c5f2.jpg +0 -0
  701. package/kb/references/thumbs/bde8e31d62.jpg +0 -0
  702. package/kb/references/thumbs/be084e78f3.jpg +0 -0
  703. package/kb/references/thumbs/be94f170c8.jpg +0 -0
  704. package/kb/references/thumbs/bed33654f7.jpg +0 -0
  705. package/kb/references/thumbs/beeb9a0c18.jpg +0 -0
  706. package/kb/references/thumbs/bef42094dc.jpg +0 -0
  707. package/kb/references/thumbs/bf625496fa.jpg +0 -0
  708. package/kb/references/thumbs/bf771f1398.jpg +0 -0
  709. package/kb/references/thumbs/c0ddefa3d9.jpg +0 -0
  710. package/kb/references/thumbs/c0f01e536e.jpg +0 -0
  711. package/kb/references/thumbs/c1d592b678.jpg +0 -0
  712. package/kb/references/thumbs/c1e83e1b3e.jpg +0 -0
  713. package/kb/references/thumbs/c2168f8096.jpg +0 -0
  714. package/kb/references/thumbs/c249cd6b17.jpg +0 -0
  715. package/kb/references/thumbs/c2e3d4feed.jpg +0 -0
  716. package/kb/references/thumbs/c3cec01df1.jpg +0 -0
  717. package/kb/references/thumbs/c47bedb42d.jpg +0 -0
  718. package/kb/references/thumbs/c4b03b4680.jpg +0 -0
  719. package/kb/references/thumbs/c4e6d18ec3.jpg +0 -0
  720. package/kb/references/thumbs/c5477e2877.jpg +0 -0
  721. package/kb/references/thumbs/c566794674.jpg +0 -0
  722. package/kb/references/thumbs/c5b945afbb.jpg +0 -0
  723. package/kb/references/thumbs/c5e4659497.jpg +0 -0
  724. package/kb/references/thumbs/c622786702.jpg +0 -0
  725. package/kb/references/thumbs/c6250649ca.jpg +0 -0
  726. package/kb/references/thumbs/c6261a9526.jpg +0 -0
  727. package/kb/references/thumbs/c62e609076.jpg +0 -0
  728. package/kb/references/thumbs/c6602d3e85.jpg +0 -0
  729. package/kb/references/thumbs/c6c1a16e40.jpg +0 -0
  730. package/kb/references/thumbs/c77f932157.jpg +0 -0
  731. package/kb/references/thumbs/c79788f01e.jpg +0 -0
  732. package/kb/references/thumbs/c7a511ad1e.jpg +0 -0
  733. package/kb/references/thumbs/c7acfbc3c8.jpg +0 -0
  734. package/kb/references/thumbs/c7bb6d1bb8.jpg +0 -0
  735. package/kb/references/thumbs/c829eadcb9.jpg +0 -0
  736. package/kb/references/thumbs/c891fd9d85.jpg +0 -0
  737. package/kb/references/thumbs/c89f812ee3.jpg +0 -0
  738. package/kb/references/thumbs/c8a85b9f61.jpg +0 -0
  739. package/kb/references/thumbs/c8fdf85c9a.jpg +0 -0
  740. package/kb/references/thumbs/c961ac1031.jpg +0 -0
  741. package/kb/references/thumbs/c9fd3f88d8.jpg +0 -0
  742. package/kb/references/thumbs/ca0d6399c3.jpg +0 -0
  743. package/kb/references/thumbs/ca316c83e4.jpg +0 -0
  744. package/kb/references/thumbs/ca3b93aa0d.jpg +0 -0
  745. package/kb/references/thumbs/cb0596a85b.jpg +0 -0
  746. package/kb/references/thumbs/cb95a5c3ef.jpg +0 -0
  747. package/kb/references/thumbs/cbe238b656.jpg +0 -0
  748. package/kb/references/thumbs/cbf530e608.jpg +0 -0
  749. package/kb/references/thumbs/cc173494ec.jpg +0 -0
  750. package/kb/references/thumbs/ccb664bddf.jpg +0 -0
  751. package/kb/references/thumbs/ccf69d36cd.jpg +0 -0
  752. package/kb/references/thumbs/ccf759db42.jpg +0 -0
  753. package/kb/references/thumbs/cd2a285807.jpg +0 -0
  754. package/kb/references/thumbs/cd4a24a8ca.jpg +0 -0
  755. package/kb/references/thumbs/cdb3fe8938.jpg +0 -0
  756. package/kb/references/thumbs/cdce1b9bc6.jpg +0 -0
  757. package/kb/references/thumbs/cde3aa761a.jpg +0 -0
  758. package/kb/references/thumbs/ce9d5cd9c2.jpg +0 -0
  759. package/kb/references/thumbs/ceb01f8a34.jpg +0 -0
  760. package/kb/references/thumbs/cee15c98d0.jpg +0 -0
  761. package/kb/references/thumbs/cf6944ddae.jpg +0 -0
  762. package/kb/references/thumbs/d15dd21cd8.jpg +0 -0
  763. package/kb/references/thumbs/d1633bf2ed.jpg +0 -0
  764. package/kb/references/thumbs/d16a838000.jpg +0 -0
  765. package/kb/references/thumbs/d1cf87e9f0.jpg +0 -0
  766. package/kb/references/thumbs/d32511d913.jpg +0 -0
  767. package/kb/references/thumbs/d327e9dedd.jpg +0 -0
  768. package/kb/references/thumbs/d35bf6c85e.jpg +0 -0
  769. package/kb/references/thumbs/d37afc9d61.jpg +0 -0
  770. package/kb/references/thumbs/d3b66655c7.jpg +0 -0
  771. package/kb/references/thumbs/d40b4172b6.jpg +0 -0
  772. package/kb/references/thumbs/d4c40d1824.jpg +0 -0
  773. package/kb/references/thumbs/d4cb55a4b6.jpg +0 -0
  774. package/kb/references/thumbs/d4f0c30f7e.jpg +0 -0
  775. package/kb/references/thumbs/d51cce3ae5.jpg +0 -0
  776. package/kb/references/thumbs/d52948f9ba.jpg +0 -0
  777. package/kb/references/thumbs/d62bd3cba4.jpg +0 -0
  778. package/kb/references/thumbs/d668a21c92.jpg +0 -0
  779. package/kb/references/thumbs/d685072c52.jpg +0 -0
  780. package/kb/references/thumbs/d6d7b96093.jpg +0 -0
  781. package/kb/references/thumbs/d7cd874b21.jpg +0 -0
  782. package/kb/references/thumbs/d7e111736a.jpg +0 -0
  783. package/kb/references/thumbs/d88325f832.jpg +0 -0
  784. package/kb/references/thumbs/d9272ded76.jpg +0 -0
  785. package/kb/references/thumbs/d962e7c654.jpg +0 -0
  786. package/kb/references/thumbs/d97f000ee2.jpg +0 -0
  787. package/kb/references/thumbs/d9c1ae2543.jpg +0 -0
  788. package/kb/references/thumbs/d9ccb3cac8.jpg +0 -0
  789. package/kb/references/thumbs/da99019680.jpg +0 -0
  790. package/kb/references/thumbs/da9b8bc615.jpg +0 -0
  791. package/kb/references/thumbs/daafbee2c1.jpg +0 -0
  792. package/kb/references/thumbs/db0f11f143.jpg +0 -0
  793. package/kb/references/thumbs/db5dd367f5.jpg +0 -0
  794. package/kb/references/thumbs/db69677866.jpg +0 -0
  795. package/kb/references/thumbs/db87c1956e.jpg +0 -0
  796. package/kb/references/thumbs/dbb86d8bda.jpg +0 -0
  797. package/kb/references/thumbs/dbd3a8ff2a.jpg +0 -0
  798. package/kb/references/thumbs/dbdf4b2794.jpg +0 -0
  799. package/kb/references/thumbs/dd4c19b4b1.jpg +0 -0
  800. package/kb/references/thumbs/dd98d9f6fa.jpg +0 -0
  801. package/kb/references/thumbs/ddb00e3b6a.jpg +0 -0
  802. package/kb/references/thumbs/dde3541a5c.jpg +0 -0
  803. package/kb/references/thumbs/de2a4da502.jpg +0 -0
  804. package/kb/references/thumbs/de4c387a66.jpg +0 -0
  805. package/kb/references/thumbs/de5618fa82.jpg +0 -0
  806. package/kb/references/thumbs/de6bec2538.jpg +0 -0
  807. package/kb/references/thumbs/dea13cbb1f.jpg +0 -0
  808. package/kb/references/thumbs/deff9202aa.jpg +0 -0
  809. package/kb/references/thumbs/df12835f8d.jpg +0 -0
  810. package/kb/references/thumbs/df57acbb3d.jpg +0 -0
  811. package/kb/references/thumbs/df8265009e.jpg +0 -0
  812. package/kb/references/thumbs/dfc99a1e8e.jpg +0 -0
  813. package/kb/references/thumbs/dfc9fde460.jpg +0 -0
  814. package/kb/references/thumbs/e038348eee.jpg +0 -0
  815. package/kb/references/thumbs/e04c2ae1d5.jpg +0 -0
  816. package/kb/references/thumbs/e070345c43.jpg +0 -0
  817. package/kb/references/thumbs/e0a0c84d47.jpg +0 -0
  818. package/kb/references/thumbs/e0af1e6b9e.jpg +0 -0
  819. package/kb/references/thumbs/e1025942c4.jpg +0 -0
  820. package/kb/references/thumbs/e11b6f5b82.jpg +0 -0
  821. package/kb/references/thumbs/e1553de3fc.jpg +0 -0
  822. package/kb/references/thumbs/e162ebe7cd.jpg +0 -0
  823. package/kb/references/thumbs/e1f1e531d8.jpg +0 -0
  824. package/kb/references/thumbs/e20842e5c9.jpg +0 -0
  825. package/kb/references/thumbs/e24e7d949b.jpg +0 -0
  826. package/kb/references/thumbs/e2a3e5d10a.jpg +0 -0
  827. package/kb/references/thumbs/e2de02615a.jpg +0 -0
  828. package/kb/references/thumbs/e305dad7dd.jpg +0 -0
  829. package/kb/references/thumbs/e52e3ef97f.jpg +0 -0
  830. package/kb/references/thumbs/e570e92d06.jpg +0 -0
  831. package/kb/references/thumbs/e583932fb9.jpg +0 -0
  832. package/kb/references/thumbs/e5da3c038f.jpg +0 -0
  833. package/kb/references/thumbs/e657634af3.jpg +0 -0
  834. package/kb/references/thumbs/e67946e3e1.jpg +0 -0
  835. package/kb/references/thumbs/e69e0f3639.jpg +0 -0
  836. package/kb/references/thumbs/e6ebe66031.jpg +0 -0
  837. package/kb/references/thumbs/e7db9563c9.jpg +0 -0
  838. package/kb/references/thumbs/e84a4c3b7b.jpg +0 -0
  839. package/kb/references/thumbs/e84cf52c27.jpg +0 -0
  840. package/kb/references/thumbs/e8707cf6e8.jpg +0 -0
  841. package/kb/references/thumbs/e888890b40.jpg +0 -0
  842. package/kb/references/thumbs/e8a502b418.jpg +0 -0
  843. package/kb/references/thumbs/e8ba68371d.jpg +0 -0
  844. package/kb/references/thumbs/e9098f54cc.jpg +0 -0
  845. package/kb/references/thumbs/e9144deae9.jpg +0 -0
  846. package/kb/references/thumbs/e93e98d757.jpg +0 -0
  847. package/kb/references/thumbs/e9762dd435.jpg +0 -0
  848. package/kb/references/thumbs/e9db4544c8.jpg +0 -0
  849. package/kb/references/thumbs/e9ddffeacd.jpg +0 -0
  850. package/kb/references/thumbs/e9e2cf1d7e.jpg +0 -0
  851. package/kb/references/thumbs/ea1e23e623.jpg +0 -0
  852. package/kb/references/thumbs/ea41200f5e.jpg +0 -0
  853. package/kb/references/thumbs/eaf4916e1a.jpg +0 -0
  854. package/kb/references/thumbs/eb2c505fc8.jpg +0 -0
  855. package/kb/references/thumbs/eb47943693.jpg +0 -0
  856. package/kb/references/thumbs/eb4ffd6625.jpg +0 -0
  857. package/kb/references/thumbs/eb82ac0a4d.jpg +0 -0
  858. package/kb/references/thumbs/ebeb345ade.jpg +0 -0
  859. package/kb/references/thumbs/ec4e2aba0a.jpg +0 -0
  860. package/kb/references/thumbs/ed683bc9f7.jpg +0 -0
  861. package/kb/references/thumbs/ed9e236a84.jpg +0 -0
  862. package/kb/references/thumbs/ee45e1caea.jpg +0 -0
  863. package/kb/references/thumbs/ee50bbf2e7.jpg +0 -0
  864. package/kb/references/thumbs/eed6ad3b7b.jpg +0 -0
  865. package/kb/references/thumbs/eee247fd70.jpg +0 -0
  866. package/kb/references/thumbs/ef87b6cb99.jpg +0 -0
  867. package/kb/references/thumbs/ef87dccf04.jpg +0 -0
  868. package/kb/references/thumbs/ef941bba1e.jpg +0 -0
  869. package/kb/references/thumbs/effc14fb2c.jpg +0 -0
  870. package/kb/references/thumbs/f04aa5a191.jpg +0 -0
  871. package/kb/references/thumbs/f13f12485f.jpg +0 -0
  872. package/kb/references/thumbs/f16a5c0fd4.jpg +0 -0
  873. package/kb/references/thumbs/f1ba7a7a8f.jpg +0 -0
  874. package/kb/references/thumbs/f1bc4c9c19.jpg +0 -0
  875. package/kb/references/thumbs/f1ee827878.jpg +0 -0
  876. package/kb/references/thumbs/f21736aeff.jpg +0 -0
  877. package/kb/references/thumbs/f22bc41213.jpg +0 -0
  878. package/kb/references/thumbs/f266aaffcc.jpg +0 -0
  879. package/kb/references/thumbs/f2c0ed0d65.jpg +0 -0
  880. package/kb/references/thumbs/f32ac710fd.jpg +0 -0
  881. package/kb/references/thumbs/f32b697ff6.jpg +0 -0
  882. package/kb/references/thumbs/f39c883904.jpg +0 -0
  883. package/kb/references/thumbs/f3b9d55e6e.jpg +0 -0
  884. package/kb/references/thumbs/f3c1763e14.jpg +0 -0
  885. package/kb/references/thumbs/f40853fd43.jpg +0 -0
  886. package/kb/references/thumbs/f4fd07dc4d.jpg +0 -0
  887. package/kb/references/thumbs/f50b756ee5.jpg +0 -0
  888. package/kb/references/thumbs/f51272e9b3.jpg +0 -0
  889. package/kb/references/thumbs/f538895eee.jpg +0 -0
  890. package/kb/references/thumbs/f5d28081b5.jpg +0 -0
  891. package/kb/references/thumbs/f6046c9501.jpg +0 -0
  892. package/kb/references/thumbs/f62e4af316.jpg +0 -0
  893. package/kb/references/thumbs/f6f6bffeb8.jpg +0 -0
  894. package/kb/references/thumbs/f736e00af6.jpg +0 -0
  895. package/kb/references/thumbs/f7932da47d.jpg +0 -0
  896. package/kb/references/thumbs/f879e118ca.jpg +0 -0
  897. package/kb/references/thumbs/f88257215d.jpg +0 -0
  898. package/kb/references/thumbs/f88c45a6d7.jpg +0 -0
  899. package/kb/references/thumbs/f89a7b646e.jpg +0 -0
  900. package/kb/references/thumbs/f8a1e7a274.jpg +0 -0
  901. package/kb/references/thumbs/f9183cf2b6.jpg +0 -0
  902. package/kb/references/thumbs/f995de5ce9.jpg +0 -0
  903. package/kb/references/thumbs/f9ada2c3e1.jpg +0 -0
  904. package/kb/references/thumbs/f9d4616f89.jpg +0 -0
  905. package/kb/references/thumbs/f9f4307bb0.jpg +0 -0
  906. package/kb/references/thumbs/fa070122c7.jpg +0 -0
  907. package/kb/references/thumbs/fa29cc1369.jpg +0 -0
  908. package/kb/references/thumbs/fa791a4dab.jpg +0 -0
  909. package/kb/references/thumbs/fa8060509e.jpg +0 -0
  910. package/kb/references/thumbs/fafeed4003.jpg +0 -0
  911. package/kb/references/thumbs/fb1c024f38.jpg +0 -0
  912. package/kb/references/thumbs/fb77aa28b3.jpg +0 -0
  913. package/kb/references/thumbs/fb9f7f1966.jpg +0 -0
  914. package/kb/references/thumbs/fba8a8c2da.jpg +0 -0
  915. package/kb/references/thumbs/fce2754c36.jpg +0 -0
  916. package/kb/references/thumbs/fce2fb83df.jpg +0 -0
  917. package/kb/references/thumbs/fd4c51bb47.jpg +0 -0
  918. package/kb/references/thumbs/fd8c269817.jpg +0 -0
  919. package/kb/references/thumbs/fdb7b250ca.jpg +0 -0
  920. package/kb/references/thumbs/fe18088de8.jpg +0 -0
  921. package/kb/references/thumbs/fe4f742ba7.jpg +0 -0
  922. package/kb/references/thumbs/fe64742ce7.jpg +0 -0
  923. package/kb/references/thumbs/feb5d62161.jpg +0 -0
  924. package/kb/references/thumbs/fed21b3e98.jpg +0 -0
  925. package/kb/references/thumbs/fed2205951.jpg +0 -0
  926. package/kb/references/thumbs/ffdacf1715.jpg +0 -0
  927. package/kb/sections/_buttons.md +93 -0
  928. package/kb/sections/_finish.md +325 -0
  929. package/kb/sections/about-founder-note.md +85 -0
  930. package/kb/sections/about-team-roster.md +86 -0
  931. package/kb/sections/alternating-rows-live-tiles.md +110 -0
  932. package/kb/sections/annotated-product-shot.md +105 -0
  933. package/kb/sections/asymmetric-bento-dominant.md +114 -0
  934. package/kb/sections/before-after-features.md +104 -0
  935. package/kb/sections/before-after-repair.md +107 -0
  936. package/kb/sections/bento-lead-tile.md +112 -0
  937. package/kb/sections/book-a-slot-honest.md +116 -0
  938. package/kb/sections/capability-prompt-ledger.md +68 -0
  939. package/kb/sections/case-study-band.md +113 -0
  940. package/kb/sections/centred-stack-hero.md +107 -0
  941. package/kb/sections/closing-demo-final-state.md +81 -0
  942. package/kb/sections/closing-full-bleed-line-and-form.md +86 -0
  943. package/kb/sections/closing-result-previewed.md +88 -0
  944. package/kb/sections/closing-three-real-steps.md +87 -0
  945. package/kb/sections/command-reference-table.md +70 -0
  946. package/kb/sections/comparison-old-way-bars.md +88 -0
  947. package/kb/sections/comparison-same-task-two-ways.md +88 -0
  948. package/kb/sections/day-of-the-place.md +102 -0
  949. package/kb/sections/docs-reading-rail.md +88 -0
  950. package/kb/sections/editorial-columns-hero.md +107 -0
  951. package/kb/sections/editorial-essay-pull-quote.md +112 -0
  952. package/kb/sections/events-calendar-list.md +107 -0
  953. package/kb/sections/explorable-control-demo.md +102 -0
  954. package/kb/sections/faq-open-answers-editorial.md +85 -0
  955. package/kb/sections/faq-ruled-accordion-aside.md +87 -0
  956. package/kb/sections/footer-closing-scene.md +84 -0
  957. package/kb/sections/footer-editorial-sitemap.md +85 -0
  958. package/kb/sections/footer-minimal-credits.md +80 -0
  959. package/kb/sections/full-bleed-image-band.md +103 -0
  960. package/kb/sections/full-bleed-image-hero.md +105 -0
  961. package/kb/sections/gallery-first-hero.md +109 -0
  962. package/kb/sections/horizontal-scroll-strip.md +101 -0
  963. package/kb/sections/how-i-work-own-voice.md +111 -0
  964. package/kb/sections/how-it-works-in-place.md +109 -0
  965. package/kb/sections/impact-numbers-sourced.md +109 -0
  966. package/kb/sections/install-steps-per-agent.md +77 -0
  967. package/kb/sections/masonry-real-work.md +109 -0
  968. package/kb/sections/numbered-editorial-columns.md +105 -0
  969. package/kb/sections/object-first-hero.md +106 -0
  970. package/kb/sections/object-timeline.md +105 -0
  971. package/kb/sections/one-huge-number.md +100 -0
  972. package/kb/sections/one-person-story.md +103 -0
  973. package/kb/sections/order-ahead-ticket.md +119 -0
  974. package/kb/sections/press-strip-quoted.md +106 -0
  975. package/kb/sections/pricing-comparison-table-sticky.md +94 -0
  976. package/kb/sections/pricing-free-pro-upgrade-moment.md +85 -0
  977. package/kb/sections/pricing-plan-beside-product.md +88 -0
  978. package/kb/sections/pricing-plans-ledger.md +94 -0
  979. package/kb/sections/pricing-usage-calculator.md +93 -0
  980. package/kb/sections/printed-menu-card.md +110 -0
  981. package/kb/sections/process-happening.md +102 -0
  982. package/kb/sections/project-index-ruled.md +106 -0
  983. package/kb/sections/proof-logo-cloud-with-reasons.md +82 -0
  984. package/kb/sections/proof-measured-numbers.md +88 -0
  985. package/kb/sections/proof-output-wall.md +84 -0
  986. package/kb/sections/proof-single-honest-quote.md +81 -0
  987. package/kb/sections/resources-searchable-list.md +110 -0
  988. package/kb/sections/rooms-and-rates.md +107 -0
  989. package/kb/sections/ruled-facts-table.md +108 -0
  990. package/kb/sections/ruled-list-pinned-visual.md +107 -0
  991. package/kb/sections/scroll-scrubbed-product-demo.md +103 -0
  992. package/kb/sections/self-playing-run-demo.md +104 -0
  993. package/kb/sections/services-price-ledger.md +106 -0
  994. package/kb/sections/signup-form-with-next-steps.md +86 -0
  995. package/kb/sections/signup-waitlist-place-in-line.md +90 -0
  996. package/kb/sections/spec-sheet-features.md +108 -0
  997. package/kb/sections/split-hero-live-object.md +108 -0
  998. package/kb/sections/sticky-feature-narrative.md +104 -0
  999. package/kb/sections/todays-board-hero.md +112 -0
  1000. package/kb/sections/touchable-tool-hero.md +111 -0
  1001. package/kb/sections/typographic-statement-hero.md +99 -0
  1002. package/kb/sections/visit-hours-map.md +110 -0
  1003. package/kb/sections/ways-to-help-honest.md +115 -0
  1004. package/kb/sources/design-reference.md +991 -0
  1005. package/kb/sources/product-and-docs.md +37 -0
  1006. package/kb/systems/1win/DESIGN.md +463 -0
  1007. package/kb/systems/LICENSE-awesome-design-md +21 -0
  1008. package/kb/systems/README.md +7 -0
  1009. package/kb/systems/airbnb/DESIGN.md +545 -0
  1010. package/kb/systems/airtable/DESIGN.md +554 -0
  1011. package/kb/systems/aljazeera/DESIGN.md +594 -0
  1012. package/kb/systems/apple/DESIGN.md +562 -0
  1013. package/kb/systems/binance/DESIGN.md +634 -0
  1014. package/kb/systems/bmw/DESIGN.md +544 -0
  1015. package/kb/systems/bmw-m/DESIGN.md +503 -0
  1016. package/kb/systems/bugatti/DESIGN.md +454 -0
  1017. package/kb/systems/cal/DESIGN.md +542 -0
  1018. package/kb/systems/categories.json +87 -0
  1019. package/kb/systems/claude/DESIGN.md +589 -0
  1020. package/kb/systems/clay/DESIGN.md +541 -0
  1021. package/kb/systems/clickhouse/DESIGN.md +544 -0
  1022. package/kb/systems/cohere/DESIGN.md +451 -0
  1023. package/kb/systems/coinbase/DESIGN.md +570 -0
  1024. package/kb/systems/composio/DESIGN.md +506 -0
  1025. package/kb/systems/cursor/DESIGN.md +537 -0
  1026. package/kb/systems/dell-1996/DESIGN.md +632 -0
  1027. package/kb/systems/dji/DESIGN.md +882 -0
  1028. package/kb/systems/elevenlabs/DESIGN.md +504 -0
  1029. package/kb/systems/expo/DESIGN.md +526 -0
  1030. package/kb/systems/ferrari/DESIGN.md +531 -0
  1031. package/kb/systems/figma/DESIGN.md +578 -0
  1032. package/kb/systems/framer/DESIGN.md +544 -0
  1033. package/kb/systems/hashicorp/DESIGN.md +575 -0
  1034. package/kb/systems/hp/DESIGN.md +670 -0
  1035. package/kb/systems/ibm/DESIGN.md +550 -0
  1036. package/kb/systems/intercom/DESIGN.md +546 -0
  1037. package/kb/systems/jobright/DESIGN.md +525 -0
  1038. package/kb/systems/kraken/DESIGN.md +125 -0
  1039. package/kb/systems/lamborghini/DESIGN.md +288 -0
  1040. package/kb/systems/linear.app/DESIGN.md +548 -0
  1041. package/kb/systems/lovable/DESIGN.md +298 -0
  1042. package/kb/systems/mastercard/DESIGN.md +365 -0
  1043. package/kb/systems/mercury/DESIGN.md +568 -0
  1044. package/kb/systems/meta/DESIGN.md +683 -0
  1045. package/kb/systems/minimax/DESIGN.md +746 -0
  1046. package/kb/systems/mintlify/DESIGN.md +852 -0
  1047. package/kb/systems/miro/DESIGN.md +825 -0
  1048. package/kb/systems/mistral.ai/DESIGN.md +773 -0
  1049. package/kb/systems/mongodb/DESIGN.md +767 -0
  1050. package/kb/systems/mydealz/DESIGN.md +551 -0
  1051. package/kb/systems/nerdwallet/DESIGN.md +722 -0
  1052. package/kb/systems/nike/DESIGN.md +575 -0
  1053. package/kb/systems/nintendo-2001/DESIGN.md +649 -0
  1054. package/kb/systems/notion/DESIGN.md +821 -0
  1055. package/kb/systems/nvidia/DESIGN.md +640 -0
  1056. package/kb/systems/ollama/DESIGN.md +539 -0
  1057. package/kb/systems/opencode.ai/DESIGN.md +521 -0
  1058. package/kb/systems/oracle/DESIGN.md +778 -0
  1059. package/kb/systems/oura/DESIGN.md +616 -0
  1060. package/kb/systems/pinterest/DESIGN.md +597 -0
  1061. package/kb/systems/playstation/DESIGN.md +661 -0
  1062. package/kb/systems/posthog/DESIGN.md +690 -0
  1063. package/kb/systems/raycast/DESIGN.md +669 -0
  1064. package/kb/systems/renault/DESIGN.md +589 -0
  1065. package/kb/systems/replicate/DESIGN.md +616 -0
  1066. package/kb/systems/resend/DESIGN.md +585 -0
  1067. package/kb/systems/revolut/DESIGN.md +636 -0
  1068. package/kb/systems/runwayml/DESIGN.md +244 -0
  1069. package/kb/systems/sanity/DESIGN.md +357 -0
  1070. package/kb/systems/sap/DESIGN.md +639 -0
  1071. package/kb/systems/sentry/DESIGN.md +551 -0
  1072. package/kb/systems/shopify/DESIGN.md +516 -0
  1073. package/kb/systems/slack/DESIGN.md +482 -0
  1074. package/kb/systems/spacex/DESIGN.md +363 -0
  1075. package/kb/systems/spotify/DESIGN.md +246 -0
  1076. package/kb/systems/starbucks/DESIGN.md +580 -0
  1077. package/kb/systems/stripe/DESIGN.md +487 -0
  1078. package/kb/systems/supabase/DESIGN.md +462 -0
  1079. package/kb/systems/superhuman/DESIGN.md +448 -0
  1080. package/kb/systems/tesla/DESIGN.md +286 -0
  1081. package/kb/systems/theverge/DESIGN.md +339 -0
  1082. package/kb/systems/together.ai/DESIGN.md +633 -0
  1083. package/kb/systems/uber/DESIGN.md +636 -0
  1084. package/kb/systems/vercel/DESIGN.md +736 -0
  1085. package/kb/systems/vodafone/DESIGN.md +538 -0
  1086. package/kb/systems/voltagent/DESIGN.md +521 -0
  1087. package/kb/systems/warp/DESIGN.md +526 -0
  1088. package/kb/systems/webflow/DESIGN.md +588 -0
  1089. package/kb/systems/wired/DESIGN.md +497 -0
  1090. package/kb/systems/wise/DESIGN.md +544 -0
  1091. package/kb/systems/x.ai/DESIGN.md +465 -0
  1092. package/kb/systems/zapier/DESIGN.md +537 -0
  1093. package/kb/taste/garvit-by-job.md +46 -0
  1094. package/kb/taste/garvit-portfolio.md +94 -0
  1095. package/kb/universal/color-roles.md +26 -0
  1096. package/kb/universal/copy.md +16 -0
  1097. package/kb/universal/details.md +31 -0
  1098. package/kb/universal/first-screen.md +30 -0
  1099. package/kb/universal/fit-the-codebase.md +29 -0
  1100. package/kb/universal/layout-width.md +28 -0
  1101. package/kb/universal/motion-feedback.md +23 -0
  1102. package/kb/universal/signature.md +29 -0
  1103. package/kb/universal/states.md +17 -0
  1104. package/kb/universal/type-app.md +33 -0
  1105. package/kb/universal/type-marketing.md +28 -0
  1106. package/package.json +36 -4
  1107. package/scripts/pack-assets.mjs +48 -0
  1108. package/skill/palate/SKILL.md +261 -0
  1109. package/src/auth-recheck.mjs +4 -0
  1110. package/src/auth.mjs +416 -0
  1111. package/src/capture.mjs +182 -0
  1112. package/src/catalog/classify.mjs +96 -0
  1113. package/src/catalog/curated.mjs +128 -0
  1114. package/src/catalog/index-build.mjs +67 -0
  1115. package/src/catalog/literal.mjs +146 -0
  1116. package/src/catalog/store.mjs +40 -0
  1117. package/src/catalog/vibrant.mjs +126 -0
  1118. package/src/check.mjs +93 -0
  1119. package/src/concept.mjs +157 -0
  1120. package/src/context.mjs +226 -0
  1121. package/src/copy.mjs +188 -0
  1122. package/src/devserver.mjs +135 -0
  1123. package/src/fontgenre.mjs +44 -0
  1124. package/src/guard-agents.mjs +213 -0
  1125. package/src/guard.mjs +377 -0
  1126. package/src/kb.mjs +91 -0
  1127. package/src/look.mjs +312 -0
  1128. package/src/loop/ambition.mjs +620 -0
  1129. package/src/loop/animate.mjs +70 -0
  1130. package/src/loop/artdirection.mjs +264 -0
  1131. package/src/loop/bench.mjs +184 -0
  1132. package/src/loop/benchpick.mjs +155 -0
  1133. package/src/loop/blueprint.mjs +620 -0
  1134. package/src/loop/board.html +180 -0
  1135. package/src/loop/build.mjs +393 -0
  1136. package/src/loop/buttons.mjs +413 -0
  1137. package/src/loop/common.mjs +206 -0
  1138. package/src/loop/cost.mjs +63 -0
  1139. package/src/loop/craft.mjs +152 -0
  1140. package/src/loop/craftchecks.mjs +148 -0
  1141. package/src/loop/critique.mjs +393 -0
  1142. package/src/loop/details.mjs +225 -0
  1143. package/src/loop/direction.html +168 -0
  1144. package/src/loop/direction.mjs +256 -0
  1145. package/src/loop/directions.json +8 -0
  1146. package/src/loop/explore.mjs +219 -0
  1147. package/src/loop/fail.mjs +110 -0
  1148. package/src/loop/fix.mjs +194 -0
  1149. package/src/loop/floor.mjs +677 -0
  1150. package/src/loop/forget.mjs +52 -0
  1151. package/src/loop/gate.mjs +1053 -0
  1152. package/src/loop/grid.html +123 -0
  1153. package/src/loop/growth.mjs +118 -0
  1154. package/src/loop/icons.mjs +109 -0
  1155. package/src/loop/imagery.mjs +1280 -0
  1156. package/src/loop/judge-api.mjs +245 -0
  1157. package/src/loop/judge.mjs +167 -0
  1158. package/src/loop/layouts.mjs +492 -0
  1159. package/src/loop/library.mjs +82 -0
  1160. package/src/loop/lookplan.mjs +182 -0
  1161. package/src/loop/lookvec.mjs +645 -0
  1162. package/src/loop/match.mjs +923 -0
  1163. package/src/loop/matched.mjs +26 -0
  1164. package/src/loop/myrefs.mjs +151 -0
  1165. package/src/loop/pick.mjs +213 -0
  1166. package/src/loop/picker.html +118 -0
  1167. package/src/loop/plan.mjs +289 -0
  1168. package/src/loop/polish.mjs +39 -0
  1169. package/src/loop/research-learn.mjs +41 -0
  1170. package/src/loop/research.mjs +1130 -0
  1171. package/src/loop/rulereview.mjs +146 -0
  1172. package/src/loop/rules-board.html +199 -0
  1173. package/src/loop/rules.mjs +939 -0
  1174. package/src/loop/similar.mjs +276 -0
  1175. package/src/loop/states-source.mjs +258 -0
  1176. package/src/loop/states.mjs +1547 -0
  1177. package/src/loop/stats.mjs +78 -0
  1178. package/src/loop/taste.mjs +81 -0
  1179. package/src/loop/timeline.mjs +149 -0
  1180. package/src/loop/variants.mjs +228 -0
  1181. package/src/loop/vary.mjs +249 -0
  1182. package/src/mcp/server.mjs +1246 -0
  1183. package/src/motion.mjs +207 -0
  1184. package/src/moves.mjs +242 -0
  1185. package/src/novelty.mjs +116 -0
  1186. package/src/page-ambition.js +181 -0
  1187. package/src/page-craft.js +724 -0
  1188. package/src/page-details.js +415 -0
  1189. package/src/page-devices.js +365 -0
  1190. package/src/page-fingerprint.js +281 -0
  1191. package/src/page-gate.js +1307 -0
  1192. package/src/page-look.js +698 -0
  1193. package/src/page-metrics.js +78 -0
  1194. package/src/page-principles.js +1167 -0
  1195. package/src/page-rules.js +308 -0
  1196. package/src/page-sections.js +211 -0
  1197. package/src/page-states.js +703 -0
  1198. package/src/paths.mjs +13 -0
  1199. package/src/png.mjs +107 -0
  1200. package/src/point/auto.mjs +224 -0
  1201. package/src/point/locate.mjs +114 -0
  1202. package/src/point/overlay.js +1516 -0
  1203. package/src/point/server.mjs +1122 -0
  1204. package/src/point/trail.mjs +219 -0
  1205. package/src/pool.mjs +80 -0
  1206. package/src/principles.mjs +279 -0
  1207. package/src/refs.mjs +299 -0
  1208. package/src/robots.mjs +145 -0
  1209. package/src/sections.mjs +210 -0
  1210. package/src/shoot.mjs +235 -0
  1211. package/src/systems/apply.mjs +355 -0
  1212. package/src/systems/load.mjs +251 -0
  1213. package/src/systems/pick.mjs +213 -0
  1214. package/templates/vite-react-tw/index.html +12 -0
  1215. package/templates/vite-react-tw/package.json +25 -0
  1216. package/templates/vite-react-tw/src/App.tsx +3 -0
  1217. package/templates/vite-react-tw/src/index.css +1 -0
  1218. package/templates/vite-react-tw/src/main.tsx +10 -0
  1219. package/templates/vite-react-tw/tsconfig.app.json +26 -0
  1220. package/templates/vite-react-tw/tsconfig.json +7 -0
  1221. package/templates/vite-react-tw/tsconfig.node.json +23 -0
  1222. package/templates/vite-react-tw/vite.config.ts +8 -0
package/src/shoot.mjs ADDED
@@ -0,0 +1,235 @@
1
+ // `palate shoot <route>`: render the page, screenshot it at each width, and report what is measurably off,
2
+ // so the agent can look at its own work and fix it. Starts the project's dev server (any common stack)
3
+ // unless --url is given.
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import { createRequire } from "node:module";
7
+ import { fileURLToPath } from "node:url";
8
+ import { acquireBrowser, acquireServer } from "./pool.mjs";
9
+ import { measurePrinciples, principlesReport } from "./principles.mjs";
10
+ import { loopOfRoute, mark } from "./loop/timeline.mjs";
11
+ import { MOTION_INIT, scrollThrough, shootFull } from "./look.mjs";
12
+ import { activeRules, appliesTo, checkRules, measureRules, projectOf, routeTags, rulesReport, statesFactsFor } from "./loop/rules.mjs";
13
+
14
+ export { freePort, kill, waitFor } from "./devserver.mjs";
15
+ export { launch } from "./pool.mjs";
16
+
17
+ const here = path.dirname(fileURLToPath(import.meta.url));
18
+ const metricsScript = fs.readFileSync(path.join(here, "page-metrics.js"), "utf8").trim().replace(/;\s*$/, "");
19
+ const fingerprintScript = fs.readFileSync(path.join(here, "page-fingerprint.js"), "utf8").trim().replace(/;\s*$/, "");
20
+ const axePath = createRequire(import.meta.url).resolve("axe-core/axe.min.js");
21
+
22
+ // Git Bash on Windows rewrites "/team" to "C:/Program Files/Git/team" (and "/m/today" to "M:/today"). A route
23
+ // never starts with a drive, so a value like that is refused with what to do, before it is stored anywhere
24
+ // (research, direction and blueprint JSON keep the route). "//team" (Git Bash's escape) and "team" are accepted.
25
+ export const ROUTE_IS_PATH = 'That route looks like a file path (Git Bash rewrites "/"): pass //, or set MSYS_NO_PATHCONV=1';
26
+ export const looksLikePath = (raw) => /^([A-Za-z]:([\\/]|$)|\\\\)/.test(String(raw ?? "").trim());
27
+ export function normalizeRoute(raw) {
28
+ const s = String(raw ?? "").trim();
29
+ if (looksLikePath(s)) throw new Error(`${ROUTE_IS_PATH} (got "${s}").`);
30
+ const r = s.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
31
+ return r.startsWith("/") ? r : `/${r}`;
32
+ }
33
+
34
+ async function resolveReference(ref) {
35
+ if (fs.existsSync(ref)) return ref;
36
+ const { allRecords, fetchImage } = await import("./refs.mjs");
37
+ const record = allRecords().find((r) => r.id === ref);
38
+ return record ? fetchImage(record) : undefined;
39
+ }
40
+
41
+ async function sideBySide(browser, ours, theirs, out, label) {
42
+ const uri = (f) => `data:image/${/\.jpe?g$/i.test(f) ? "jpeg" : /\.webp$/i.test(f) ? "webp" : "png"};base64,${fs.readFileSync(f).toString("base64")}`;
43
+ const page = await browser.newPage({ viewport: { width: 1600, height: 600 } });
44
+ await page.setContent(`<!doctype html><body style="margin:0;background:#eee;font:14px system-ui">
45
+ <div id="w" style="display:inline-flex;gap:16px;padding:16px">
46
+ <figure style="margin:0;width:760px"><figcaption style="margin-bottom:6px">Ours</figcaption><img src="${uri(ours)}" style="width:100%;border:1px solid #ccc"></figure>
47
+ <figure style="margin:0;width:760px"><figcaption style="margin-bottom:6px">Reference: ${label.replace(/[<>&"]/g, "")}</figcaption><img src="${uri(theirs)}" style="width:100%;border:1px solid #ccc"></figure>
48
+ </div></body>`);
49
+ await page.locator("#w").screenshot({ path: out });
50
+ await page.close();
51
+ }
52
+
53
+ // fold: a quick look while building: the first screen only (no full-page screenshot) and no principles pass,
54
+ // which runs on the winner.
55
+ // like: projects the user asked to match; the similarity gate lets their look through.
56
+ // tablet: also 1024 and 768 (tablet is where a hero photo gets blown up behind its text); palate gate always
57
+ // renders those, so a shoot adds them only when asked.
58
+ export const TABLET_WIDTHS = [1440, 1024, 768, 390];
59
+ export async function shoot(dir, rawRoute, { widths: given, tablet = false, url, compare, fold: foldOnly = false, principles: withPrinciples = !foldOnly, like = [] } = {}) {
60
+ const widths = given ?? (tablet ? TABLET_WIDTHS : [1440, 390]);
61
+ const route = normalizeRoute(rawRoute);
62
+ const server = await acquireServer(dir, { url });
63
+ const base = server.base;
64
+
65
+ const slug = route.replace(/[^a-z0-9]+/gi, "-").replace(/^-|-$/g, "") || "home";
66
+ const outDir = path.join(dir, ".palate", "shots", slug);
67
+ fs.mkdirSync(outDir, { recursive: true });
68
+ fs.writeFileSync(path.join(dir, ".palate", ".gitignore"), "*\n");
69
+ const round = fs.readdirSync(outDir).filter((f) => f.endsWith("-fold.png")).reduce((n, f) => Math.max(n, Number(f.match(/^r(\d+)/)?.[1] ?? 0)), 0) + 1;
70
+
71
+ const { browser, release } = await acquireBrowser();
72
+ const report = [`# palate shoot ${route} (round ${round})${foldOnly ? ", first screen only" : ""}`, ""];
73
+ const files = [];
74
+ let fingerprint;
75
+ // The look fingerprint (loop/lookvec.mjs), measured on full shoots at the first desktop width.
76
+ let look = null;
77
+ let gate = null;
78
+ // The user's rules, checked once at the first desktop width.
79
+ let rules = null;
80
+ const allRules = activeRules();
81
+ try {
82
+ for (const width of widths) {
83
+ const height = width < 600 ? 844 : 900;
84
+ const ctx = await browser.newContext({ viewport: { width, height } });
85
+ const page = await ctx.newPage();
86
+ // Counts what moves (for the motion rule); patches nothing the page relies on.
87
+ if (allRules.length) await page.addInitScript(MOTION_INIT);
88
+ const errors = [];
89
+ page.on("pageerror", (e) => errors.push(e.message));
90
+ page.on("console", (m) => m.type() === "error" && errors.push(m.text()));
91
+ // Vite may reload the page once while it optimises newly found dependencies; measure again if so.
92
+ let m, contrastNodes, fold, full, principles;
93
+ for (let attempt = 0; ; attempt++) {
94
+ try {
95
+ await page.goto(base + route, { waitUntil: "networkidle", timeout: 30_000 }).catch((e) => errors.push(e.message));
96
+ await page.waitForTimeout(700);
97
+ // A build error renders as the dev server's overlay, not as the page.
98
+ const overlay = await page.evaluate(() => document.querySelector("vite-error-overlay")?.shadowRoot?.querySelector(".message")?.textContent ?? null).catch(() => null);
99
+ if (overlay) errors.unshift(`The page did not build: ${overlay.trim().slice(0, 300)}`);
100
+ fold = path.join(outDir, `r${round}-w${width}-fold.png`);
101
+ full = path.join(outDir, `r${round}-w${width}-full.png`);
102
+ await page.screenshot({ path: fold });
103
+ // Scroll through first so lazy images load and scroll reveals fire, then shoot the whole page.
104
+ if (!foldOnly) {
105
+ await scrollThrough(page, { pause: 80 });
106
+ await shootFull(page, full);
107
+ }
108
+ if (!attempt) files.push(fold, ...(foldOnly ? [] : [full]));
109
+ m = await page.evaluate(`(${metricsScript})()`);
110
+ await page.addScriptTag({ path: axePath });
111
+ contrastNodes = await page.evaluate(`axe.run(document, { runOnly: ["color-contrast"] }).then(r => r.violations.flatMap(v => v.nodes.map(n => (n.target.join(' ') + ' "' + (n.html.replace(/<[^>]+>/g, '').trim().slice(0, 30)) + '" ' + ((n.any[0] && n.any[0].data && n.any[0].data.contrastRatio) || '') + ':1'))))`);
112
+ // Alignment, hierarchy, spacing, type and consistency (scrolls to the top, so after the screenshots).
113
+ principles = withPrinciples ? await measurePrinciples(page).catch(() => null) : null;
114
+ if (!fingerprint && !overlay && width >= 1000) fingerprint = await page.evaluate(`(${fingerprintScript})()`).catch(() => undefined);
115
+ if (!foldOnly && !look && !overlay && width >= 1000) look = await import("./loop/lookvec.mjs").then((L) => L.measureLook(page)).then((m) => m.look).catch(() => null);
116
+ break;
117
+ } catch (e) {
118
+ if (attempt || !/context was destroyed|navigat/i.test(e.message)) throw e;
119
+ await page.waitForLoadState("networkidle").catch(() => {});
120
+ }
121
+ }
122
+ const contrast = contrastNodes.length;
123
+ // The rules: scroll through once (lazy parts load, reveals fire), measure, check those for this kind of screen.
124
+ if (allRules.length && !rules && width >= 1000 && !errors.some((e) => e.startsWith("The page did not build"))) {
125
+ try {
126
+ // A dev server can reload the page mid-scroll (another agent saved a file): then wait and scroll again.
127
+ let navs = 0;
128
+ page.on("framenavigated", (f) => f === page.mainFrame() && navs++);
129
+ await scrollThrough(page, { pause: 90 });
130
+ const broken = () => page.evaluate(() => document.body.innerText.length < 200).catch(() => true);
131
+ if (navs || (await broken())) {
132
+ await page.waitForLoadState("networkidle", { timeout: 30_000 }).catch(() => {});
133
+ await page.waitForTimeout(900);
134
+ await scrollThrough(page, { pause: 90 });
135
+ }
136
+ // The page itself broke while scrolling (a runtime error): measure it as loaded, unscrolled, and say so.
137
+ let note = null;
138
+ if (await broken()) {
139
+ note = `the page broke while scrolling${errors.length ? ` (${errors.at(-1).slice(0, 140)})` : ""}, so the rules were checked on the page as loaded, without scrolling`;
140
+ await page.reload({ waitUntil: "networkidle", timeout: 30_000 }).catch(() => {});
141
+ await page.waitForTimeout(900);
142
+ }
143
+ const { facts, sections } = await measureRules(page, allRules);
144
+ // Empty, loading, error … can't be seen in the page as it loads: they come from the latest palate states run.
145
+ Object.assign(facts, statesFactsFor(dir, route) ?? {});
146
+ if (note) facts.note = note;
147
+ const tags = routeTags(dir, route, { title: await page.title().catch(() => ""), sections });
148
+ rules = { tags, facts, results: checkRules(allRules.filter((r) => appliesTo(r, tags, { route, project: projectOf(dir) })), facts) };
149
+ fs.writeFileSync(path.join(outDir, `r${round}-rules.json`), JSON.stringify({ route, ...rules }, null, 1));
150
+ } catch (e) {
151
+ rules = { error: String(e.message).slice(0, 160), results: [] };
152
+ }
153
+ }
154
+ // The page's system across its sections (H2 sizes, section padding, buttons, cards; a photo used twice): the
155
+ // gate's page-level checks, so the one shoot of a direct fix sees a drift too.
156
+ let system = [];
157
+ if (width >= 1200 && !errors.some((e) => e.startsWith("The page did not build"))) {
158
+ try {
159
+ const { floorOnPage } = await import("./loop/floor.mjs");
160
+ const { findSections } = await import("./look.mjs");
161
+ const sections = await findSections(page);
162
+ system = (await floorOnPage(page, { width, sections, pageLevel: true })).filter((c) => c.id === "SYSTEM_DRIFT" || c.id === "PHOTO_REPEAT");
163
+ } catch {}
164
+ }
165
+ await ctx.close();
166
+
167
+ const warn = [];
168
+ if (errors.length) warn.push(`Console errors: ${errors.slice(0, 3).join(" | ")}`);
169
+ for (const c of system) warn.push(`${c.id}${c.severity === "fail" ? " (palate gate fails this)" : ""}: ${c.what}${c.fix ? `. ${c.fix}` : ""}`);
170
+ if (m.overflowX > 1) warn.push(`Page scrolls sideways by ${m.overflowX}px. Find the element wider than the screen.`);
171
+ if (m.tnumProseCount) warn.push(`Tabular figures are on ${m.tnumProseCount} text block(s) with words, e.g. "${m.tnumProse[0]}". In many fonts this spaces out commas and full stops. Apply tabular-nums only to numbers.`);
172
+ if (contrast) warn.push(`${contrast} element(s) fail colour contrast (WCAG AA): ${contrastNodes.slice(0, 3).join(" · ")}`);
173
+ if (m.tinyText) warn.push(`${m.tinyText} text element(s) under 12px.`);
174
+ if (m.fontSizes.length > 7) warn.push(`${m.fontSizes.length} different font sizes on one screen; a tight screen uses 4 to 6.`);
175
+ if (m.fontFamilies.length > 2) warn.push(`${m.fontFamilies.length} font families: ${m.fontFamilies.join(", ")}.`);
176
+ if (width >= 1200 && m.contentSpan < 55) warn.push(`Content spans only ${m.contentSpan}% of the width at ${width}px. Check whether the layout uses the screen or just floats in the middle.`);
177
+ if (width < 600 && m.smallTargets) warn.push(`${m.smallTargets} tap target(s) smaller than 24px: ${m.smallTargetList.join(", ")}.`);
178
+
179
+ report.push(`## ${width}px`);
180
+ report.push(foldOnly ? `- Screenshot: ${fold} (first screen; the page is ${m.pageHeight}px tall)` : `- Screenshots: ${fold} (first screen) and ${full} (full page, ${m.pageHeight}px tall)`);
181
+ if (!errors.some((e) => e.startsWith("The page did not build"))) {
182
+ const loop = loopOfRoute(dir, route);
183
+ if (loop) {
184
+ mark(dir, loop, "first_render", { route });
185
+ mark(dir, loop, "shot", { route });
186
+ }
187
+ }
188
+ report.push(`- Biggest text on the first screen: ${m.focal.size}px "${m.focal.text}"`);
189
+ report.push(`- Font sizes in use: ${m.fontSizes.join(", ")}`);
190
+ report.push(`- Font families: ${m.fontFamilies.join(", ")} · ${m.textColors} text colours · content spans ${m.contentSpan}% of the width`);
191
+ report.push(warn.length ? warn.map((w) => `- ⚠ ${w}`).join("\n") : "- No measurable problems. Judge the screenshot itself.");
192
+ if (principles) report.push(...principlesReport(principles, { max: 8 }));
193
+ report.push("");
194
+ }
195
+ if (rules?.results?.length) report.push(...rulesReport(rules.results).map((l, i) => (i === 0 ? `## Your rules (${rules.tags.join(", ")}; checked at ${widths.find((w) => w >= 1000)}px)` : l)), ...(rules.facts?.note ? [`- ⚠ Note: ${rules.facts.note}.`] : []), "");
196
+ else if (rules?.error) report.push(`## Your rules`, `- Could not check them: ${rules.error}`, "");
197
+ // A route built from the user's own design is theirs, not palate's: its look isn't compared or remembered.
198
+ const { matchedRoute } = await import("./loop/matched.mjs");
199
+ if (look && matchedRoute(dir, route)) report.push("## Look", "- Not compared: this route is built from the user's own design (palate match).", "");
200
+ else if (look) {
201
+ // The page's visual language in one line, and the closest look palate made recently in another project.
202
+ try {
203
+ const L = await import("./loop/lookvec.mjs");
204
+ const { projectId } = await import("./loop/layouts.mjs");
205
+ const { likeOf } = await import("./loop/similar.mjs");
206
+ const best = L.closestLook(look, { excludePid: projectId(dir), exclude: [...like, ...likeOf(dir, route)] });
207
+ await L.recordLook(dir, route, look);
208
+ const buttons = L.buttonRepeatFinding(look, { excludePid: projectId(dir), like: [...like, ...likeOf(dir, route)] });
209
+ report.push("## Look", L.lookLine(look, best, { buttons }), "");
210
+ } catch {}
211
+ }
212
+ if (fingerprint?.skeleton.length) {
213
+ const { noveltyReport } = await import("./novelty.mjs");
214
+ const novelty = noveltyReport(dir, route, fingerprint, { like });
215
+ gate = novelty.gate ?? null;
216
+ report.push(...novelty, "");
217
+ }
218
+ if (compare) {
219
+ const refImage = await resolveReference(compare);
220
+ const ours = files.find((f) => f.endsWith("-fold.png"));
221
+ if (refImage && ours) {
222
+ const file = path.join(outDir, `r${round}-compare.png`);
223
+ await sideBySide(browser, ours, refImage, file, compare);
224
+ report.push(`## Compared with ${compare}`, `- Side by side: ${file}`, "- Ask: where does ours fall short of the reference in hierarchy, type, spacing, density and finish? What is the single change that closes most of the gap?", "");
225
+ } else report.push(`- ⚠ Could not load reference "${compare}" for comparison.`, "");
226
+ }
227
+ } finally {
228
+ await release();
229
+ server.stop();
230
+ }
231
+ if (foldOnly) report.push("First screen only: the 390 check, the principles pass, details and animate run on the winner, after the pick.");
232
+ report.push("Now open the first-screen screenshots with your image-reading tool and review them with the Look checklist in the palate skill. Measurements catch bugs; they don't tell you whether the design is good.");
233
+ if (gate && !gate.pass) report.push(`palate shoot ${route}: FAILED the similarity gate. Change what it names (yourself; this isn't a question for the user), then shoot again.`);
234
+ return { report: report.join("\n"), files, rules, gate };
235
+ }
@@ -0,0 +1,355 @@
1
+ // `palate system apply <id>`: transfer a design system's craft into the project's own tokens.
2
+ // Colour roles, a named type scale (text-display … text-caption), radii, depth and section spacing go
3
+ // into the project's CSS; the project's brand accent is kept unless --no-keep-brand. Also writes
4
+ // .palate/system.md: the rules an agent follows to extend the system to anything it never showed.
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import { hueSat, luminance, parseColor } from "../catalog/classify.mjs";
8
+ import { fontClass } from "../catalog/classify.mjs";
9
+ import { loadSystems } from "./load.mjs";
10
+
11
+ const OPEN_FONTS = [
12
+ "Inter Tight", "Inter", "Geist Mono", "Geist", "Manrope", "DM Sans", "IBM Plex Sans", "IBM Plex Mono", "Plus Jakarta Sans", "Instrument Serif", "Instrument Sans",
13
+ "Fraunces", "Newsreader", "Source Serif 4", "EB Garamond", "Space Grotesk", "JetBrains Mono", "Figtree", "Outfit", "Sora", "Work Sans", "Public Sans",
14
+ "Roboto", "Open Sans", "Lora", "Playfair Display", "Cormorant Garamond", "Bricolage Grotesque", "Hanken Grotesk", "Onest", "Schibsted Grotesk", "Archivo",
15
+ ];
16
+ const FONTSOURCE = (f) => `@fontsource-variable/${f.toLowerCase().replace(/\s+/g, "-").replace("source-serif-4", "source-serif-4")}`;
17
+ const BY_CLASS = { "geometric-sans": "Geist", grotesk: "Inter", "humanist-sans": "Figtree", serif: "Newsreader", display: "Bricolage Grotesque", mono: "JetBrains Mono" };
18
+
19
+ const toHex = ([r, g, b]) => "#" + [r, g, b].map((v) => Math.round(Math.max(0, Math.min(255, v))).toString(16).padStart(2, "0")).join("");
20
+ const mix = (a, b, t) => {
21
+ const A = parseColor(a);
22
+ const B = parseColor(b);
23
+ if (!A || !B) return a;
24
+ return toHex(A.map((v, i) => v + (B[i] - v) * t));
25
+ };
26
+ const readable = (bg) => {
27
+ const rgb = parseColor(bg);
28
+ return rgb && luminance(rgb) > 0.45 ? "#0a0a0a" : "#ffffff";
29
+ };
30
+ // oklch() strings carry chroma directly; parseColor flattens them to grey.
31
+ const chromatic = (value) => {
32
+ const ok = /oklch\(\s*[\d.]+%?\s+([\d.]+)/i.exec(value ?? "");
33
+ if (ok) return Number(ok[1]) > 0.04;
34
+ const rgb = parseColor(value);
35
+ return rgb ? hueSat(rgb).s > 0.15 : false;
36
+ };
37
+
38
+ // A family an agent can actually load: the system's own if it's open, the substitute it names, or one by class.
39
+ function openFamily(family, sys) {
40
+ if (!family) return undefined;
41
+ const direct = OPEN_FONTS.find((f) => family.toLowerCase() === f.toLowerCase() || family.toLowerCase().startsWith(f.toLowerCase() + " "));
42
+ if (direct) return direct;
43
+ const cls = fontClass(family) ?? "grotesk";
44
+ const isMono = (f) => /mono/i.test(f);
45
+ // A substitute must be the same kind of face: a mono role gets a mono font, a serif role a serif.
46
+ const candidates = OPEN_FONTS.filter((f) => (cls === "mono" ? isMono(f) : !isMono(f)) && (cls === "serif" ? fontClass(f) === "serif" : fontClass(f) !== "serif"));
47
+ const note = Object.entries(sys.sections)
48
+ .filter(([k]) => /substitut|font famil|typograph/.test(k))
49
+ .map(([, v]) => v)
50
+ .join("\n");
51
+ const named = candidates.find((f) => new RegExp(`\\b${f}\\b`, "i").test(note));
52
+ return named ?? BY_CLASS[cls];
53
+ }
54
+
55
+ function typeRoles(sys) {
56
+ const t = [...sys.type].sort((a, b) => b.size - a.size);
57
+ const by = (re) => sys.type.filter((r) => re.test(r.role)).sort((a, b) => b.size - a.size);
58
+ const displays = by(/display|hero|heading-1|headline|h1|title-xl/);
59
+ const pick = (...lists) => lists.flat().find(Boolean);
60
+ const roles = {
61
+ display: pick(displays[0], t[0]),
62
+ h1: pick(displays[1], by(/heading-lg|heading-1|h1|title-lg/)[0], t[1]),
63
+ h2: pick(displays[2], by(/heading-md|heading-2|h2|headline|section/)[0], t[2]),
64
+ h3: pick(by(/card-title|heading-sm|title-md|h3|subhead|title/)[0], t[3]),
65
+ "body-lg": pick(by(/body-lg|lead|subhead/)[0]),
66
+ body: pick(by(/^body(-md)?$/)[0], by(/body/)[0]),
67
+ "body-sm": pick(by(/body-sm|small/)[0]),
68
+ caption: pick(by(/caption|micro|label|eyebrow/).reverse()[0]),
69
+ button: pick(by(/button/)[0]),
70
+ };
71
+ return completeScale(Object.fromEntries(Object.entries(roles).filter(([, v]) => v)));
72
+ }
73
+
74
+ // Every project gets the same role names, even when a DESIGN.md documents only some of them: the
75
+ // missing steps are derived from the body size, and nothing goes below 12px (the shoot floor).
76
+ function completeScale(roles) {
77
+ const body = roles.body ?? { size: 16, weight: 400, lineHeight: 1.5 };
78
+ const like = (size, extra) => ({ family: body.family, weight: body.weight ?? 400, lineHeight: body.lineHeight ?? 1.5, ...extra, size });
79
+ const out = { ...roles, body };
80
+ out["body-lg"] ??= like(Math.round(body.size * 1.125), { lineHeight: 1.55 });
81
+ out["body-sm"] ??= like(Math.max(13, body.size - 2));
82
+ out.label = like(out["body-sm"].size, { weight: 500, lineHeight: 1.4 });
83
+ out.caption = out.caption ? { ...out.caption, size: Math.max(12, out.caption.size) } : like(12, { lineHeight: 1.4 });
84
+ out.button ??= like(out["body-sm"].size, { weight: 500, lineHeight: 1 });
85
+ const order = ["display", "h1", "h2", "h3", "body-lg", "body", "body-sm", "label", "caption", "button"];
86
+ return Object.fromEntries(order.filter((k) => out[k]).map((k) => [k, out[k]]));
87
+ }
88
+
89
+ // WCAG contrast, and a colour nudged toward black or white until it reaches the ratio.
90
+ const wcag = (a, b) => {
91
+ const A = parseColor(a);
92
+ const B = parseColor(b);
93
+ if (!A || !B) return 21;
94
+ const [l1, l2] = [luminance(A), luminance(B)].sort((x, y) => y - x);
95
+ return (l1 + 0.05) / (l2 + 0.05);
96
+ };
97
+ function reach(color, against, ratio, toward) {
98
+ let c = color;
99
+ for (let i = 1; i <= 20 && wcag(c, against) < ratio; i++) c = mix(color, toward, i * 0.05);
100
+ return c;
101
+ }
102
+
103
+ // shadcn's cn() runs tailwind-merge, which reads unknown text-* classes as colours and drops a
104
+ // type role whenever a colour class follows it. Teach it the roles.
105
+ function patchCn(dir, roleNames) {
106
+ const file = ["src/lib/utils.ts", "lib/utils.ts", "src/lib/utils.js"].map((f) => path.join(dir, f)).find((f) => fs.existsSync(f));
107
+ if (!file) return undefined;
108
+ let src = fs.readFileSync(file, "utf8");
109
+ const list = roleNames.map((r) => `"${r}"`).join(", ");
110
+ const block = `// palate: the design system's type roles are font sizes; without this, tailwind-merge reads them as
111
+ // text colours and drops them when a colour class follows.
112
+ const twMerge = extendTailwindMerge({
113
+ extend: { classGroups: { "font-size": [{ text: [${list}] }] } },
114
+ });`;
115
+ if (/extendTailwindMerge/.test(src)) {
116
+ src = src.replace(/"font-size":\s*\[\{\s*text:\s*\[[^\]]*\]/, `"font-size": [{ text: [${list}]`);
117
+ } else if (/import\s*\{\s*twMerge\s*\}\s*from\s*["']tailwind-merge["'];?/.test(src)) {
118
+ src = src.replace(/import\s*\{\s*twMerge\s*\}\s*from\s*["']tailwind-merge["'];?/, 'import { extendTailwindMerge } from "tailwind-merge";');
119
+ src = src.replace(/(\n)(export function cn)/, `\n${block}\n$1$2`);
120
+ } else return undefined;
121
+ fs.writeFileSync(file, src);
122
+ return path.relative(dir, file);
123
+ }
124
+
125
+ // In a hairline system, shared primitives lose their resting drop shadows (overlays keep theirs).
126
+ function stripRestingShadows(dir) {
127
+ const uiDir = ["src/components/ui", "components/ui"].map((d) => path.join(dir, d)).find((d) => fs.existsSync(d));
128
+ if (!uiDir) return 0;
129
+ let n = 0;
130
+ for (const f of fs.readdirSync(uiDir).filter((f) => /^(button|input|select|textarea|card|checkbox|switch|tabs|badge|toggle)\.tsx$/.test(f))) {
131
+ const file = path.join(uiDir, f);
132
+ const src = fs.readFileSync(file, "utf8");
133
+ const out = src.replace(/(?<![\w:-])shadow-(xs|sm)(?![\w-])\s?/g, () => (n++, ""));
134
+ if (out !== src) fs.writeFileSync(file, out);
135
+ }
136
+ return n;
137
+ }
138
+
139
+ function firstShadow(sys) {
140
+ const text = Object.entries(sys.sections)
141
+ .filter(([k]) => /elevation|depth|shadow|card/.test(k))
142
+ .map(([, v]) => v)
143
+ .join("\n");
144
+ const m = /((?:rgba?\([^)]*\)|#[0-9a-f]{3,8})\s+-?\d+px\s+-?\d+px\s+-?\d+px(?:\s+-?\d+px)?(?:\s*,\s*(?:rgba?\([^)]*\)|#[0-9a-f]{3,8})\s+-?\d+px\s+-?\d+px\s+-?\d+px(?:\s+-?\d+px)?)*)/i.exec(text) ?? /(-?\d+px\s+-?\d+px\s+-?\d+px(?:\s+-?\d+px)?\s+(?:rgba?\([^)]*\)|#[0-9a-f]{3,8}))/i.exec(text);
145
+ return m?.[1];
146
+ }
147
+
148
+ function findTokenCss(dir) {
149
+ const candidates = ["src/index.css", "src/globals.css", "app/globals.css", "src/app/globals.css", "src/styles/globals.css", "src/tokens.css", "styles/globals.css"];
150
+ return candidates.map((c) => path.join(dir, c)).find((f) => fs.existsSync(f) && /:root\s*\{[^}]*--background\s*:/s.test(fs.readFileSync(f, "utf8")));
151
+ }
152
+
153
+ export function systemTokens(sys, { brandPrimary } = {}) {
154
+ const r = sys.roles;
155
+ const light = sys.facets.theme !== "dark";
156
+ const canvas = r.canvas;
157
+ const ink = r.ink;
158
+ const soft = r.surfaceSoft ?? mix(canvas, ink, light ? 0.035 : 0.06);
159
+ const primary = brandPrimary ?? r.primary ?? ink;
160
+ const vars = {
161
+ background: canvas,
162
+ foreground: ink,
163
+ card: r.surface && r.surface !== canvas ? r.surface : light ? mix(canvas, "#ffffff", 0.6) : mix(canvas, "#ffffff", 0.04),
164
+ "card-foreground": ink,
165
+ popover: r.surface ?? canvas,
166
+ "popover-foreground": ink,
167
+ primary,
168
+ "primary-foreground": brandPrimary ? undefined : r.onPrimary ?? readable(primary),
169
+ secondary: soft,
170
+ "secondary-foreground": ink,
171
+ muted: soft,
172
+ "muted-foreground": r.muted ?? r.body ?? mix(ink, canvas, 0.45),
173
+ accent: mix(soft, ink, light ? 0.02 : 0.04),
174
+ "accent-foreground": ink,
175
+ border: r.hairline ?? mix(canvas, ink, light ? 0.1 : 0.14),
176
+ input: r.hairlineStrong ?? r.hairline ?? mix(canvas, ink, light ? 0.16 : 0.2),
177
+ ring: primary,
178
+ destructive: r.error,
179
+ success: r.success,
180
+ warning: r.warning,
181
+ };
182
+ // Text must stay readable: muted text on every surface, and the label on the primary button.
183
+ // A kept brand colour isn't changed here; apply reports it instead.
184
+ vars["muted-foreground"] = reach(vars["muted-foreground"], [vars.muted, vars.background, vars.card].sort((a, b) => wcag(vars["muted-foreground"], a) - wcag(vars["muted-foreground"], b))[0], 4.5, light ? "#000000" : "#ffffff");
185
+ if (!brandPrimary && vars["primary-foreground"] && wcag(vars.primary, vars["primary-foreground"]) < 4.5) {
186
+ vars.primary = reach(vars.primary, vars["primary-foreground"], 4.5, luminance(parseColor(vars["primary-foreground"]) ?? [255, 255, 255]) > 0.5 ? "#000000" : "#ffffff");
187
+ vars.ring = vars.primary;
188
+ }
189
+ return Object.fromEntries(Object.entries(vars).filter(([, v]) => v));
190
+ }
191
+
192
+ function themeBlock(sys, fonts, roles = typeRoles(sys)) {
193
+ // @fontsource-variable registers each face as "<Name> Variable"; the plain name covers a local install.
194
+ const face = (f) => `"${f} Variable", "${f}"`;
195
+ const lines = ["@theme {", ` --font-sans: ${face(fonts.body)}, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;`, ` --font-display: ${face(fonts.display)}, var(--font-sans);`];
196
+ if (fonts.mono) lines.push(` --font-mono: ${face(fonts.mono)}, ui-monospace, "SF Mono", Menlo, monospace;`);
197
+ for (const [role, t] of Object.entries(roles)) {
198
+ lines.push(` --text-${role}: ${t.size / 16}rem;`);
199
+ if (t.lineHeight) lines.push(` --text-${role}--line-height: ${t.lineHeight};`);
200
+ if (t.tracking) lines.push(` --text-${role}--letter-spacing: ${t.tracking}em;`);
201
+ if (t.weight) lines.push(` --text-${role}--font-weight: ${t.weight};`);
202
+ }
203
+ const rad = sys.radii;
204
+ const radius = (k, fallback) => (rad[k] ?? fallback) !== undefined ? `${Math.min(rad[k] ?? fallback, 9999)}px` : undefined;
205
+ for (const [k, v] of [["sm", radius("sm", rad.xs)], ["md", radius("md")], ["lg", radius("lg")], ["xl", radius("xl")], ["2xl", radius("xxl", rad.xl)]]) if (v) lines.push(` --radius-${k}: ${v};`);
206
+ const shadow = firstShadow(sys);
207
+ if (shadow) lines.push(` --shadow-raised: ${shadow};`);
208
+ if (sys.spacing.section) lines.push(` --spacing-section: ${sys.spacing.section / 16}rem;`);
209
+ lines.push("}");
210
+ return { css: lines.join("\n"), roles };
211
+ }
212
+
213
+ function grammar(sys, roles, keptBrand) {
214
+ const f = sys.facets;
215
+ const rules = [];
216
+ rules.push(
217
+ f.elevation === "hairline"
218
+ ? "Depth comes from 1px hairlines (`border`) and stepped surfaces (`bg-background` → `bg-muted` → `bg-card`). No drop shadows on things at rest; only overlays (menus, dialogs) may float."
219
+ : f.elevation === "shadow"
220
+ ? "Raised surfaces use `shadow-raised` (the system's own shadow); borders stay faint or absent."
221
+ : "Use hairlines for structure and `shadow-raised` only for genuinely floating things.",
222
+ );
223
+ rules.push(`Radii: buttons and inputs \`rounded-md\` (${sys.radii.md ?? "?"}px), cards \`rounded-lg\` (${sys.radii.lg ?? "?"}px)${f.radius === "pill" ? "; primary buttons are pills (`rounded-full`)" : ""}. Never mix in other radii.`);
224
+ rules.push(
225
+ f.palette === "restrained"
226
+ ? "Colour is rare: the accent appears only on the primary action, links, focus and selection. Everything else is neutral. Status uses small dots or text, not filled badges."
227
+ : "The accent leads; supporting colours stay inside their own areas (one per category or status), never decorative.",
228
+ );
229
+ rules.push(`Type: use the named roles only (${Object.keys(roles).map((k) => `\`text-${k}\``).join(", ")}); \`text-label\` is for table headers, form labels and names in lists. Don't add weights or tracking on top of a role. Display type is ${roles.display?.weight ?? "?"} weight with ${roles.display?.tracking ?? 0}em tracking; never bold it further.`);
230
+ rules.push(`Density: body is ${roles.body?.size ?? "?"}px. ${f.density === "dense" ? "Keep rows 36–44px and gaps tight." : f.density === "airy" ? "Give content generous gaps (24–48px) and large section spacing." : "Rows 44–52px, section spacing as `py-(--spacing-section)` where it exists."}`);
231
+ if (keptBrand) rules.push("The primary colour is the project's own brand, kept on purpose. Use it the way this system uses its accent.");
232
+ rules.push("Extending the system: a component this system never showed must still look native. Build it from the same surfaces, hairlines, radii, type roles and accent rules above, then check it next to an existing component.");
233
+ return rules;
234
+ }
235
+
236
+ const trim = (s, n) => (s && s.length > n ? s.slice(0, n).replace(/\s+\S*$/, "") + " …" : s ?? "");
237
+
238
+ export function applySystem(id, dir, { keepBrand = true, typeFrom } = {}) {
239
+ const all = loadSystems();
240
+ const find = (x) => all.find((s) => s.id === x || s.name.toLowerCase() === String(x).toLowerCase());
241
+ const sys = find(id);
242
+ if (!sys) throw new Error(`No design system "${id}". Run: palate system list`);
243
+ // Blending: display, h1 and h2 (and the display face) from a second system; everything else from the first.
244
+ const donor = typeFrom ? find(typeFrom) : undefined;
245
+ if (typeFrom && !donor) throw new Error(`No design system "${typeFrom}" to take type from.`);
246
+ const typeSet = { ...typeRoles(sys), ...(donor ? Object.fromEntries(["display", "h1", "h2"].map((k) => [k, typeRoles(donor)[k]]).filter(([, v]) => v)) : {}) };
247
+ const cssFile = findTokenCss(dir);
248
+ const display = typeSet.display;
249
+ const body = typeSet.body;
250
+ const monoRole = sys.type.find((t) => /mono|code/.test(t.role));
251
+ const fonts = { display: openFamily(display?.family, donor ?? sys) ?? "Inter", body: openFamily(body?.family, sys) ?? "Inter", mono: monoRole ? openFamily(monoRole.family, sys) : undefined };
252
+
253
+ let brandPrimary;
254
+ let changes = [];
255
+ const notes = [];
256
+ if (cssFile) {
257
+ let css = fs.readFileSync(cssFile, "utf8");
258
+ fs.mkdirSync(path.join(dir, ".palate", "backup"), { recursive: true });
259
+ fs.writeFileSync(path.join(dir, ".palate", "backup", `${path.basename(cssFile)}.${Date.now()}`), css);
260
+ const root = /:root\s*\{([^}]*)\}/s.exec(css);
261
+ const currentPrimary = /--primary\s*:\s*([^;]+);/.exec(root?.[1] ?? "")?.[1]?.trim();
262
+ if (keepBrand && currentPrimary && chromatic(currentPrimary)) brandPrimary = currentPrimary;
263
+ const vars = systemTokens(sys, { brandPrimary });
264
+ let block = root[1];
265
+ for (const [k, v] of Object.entries(vars)) {
266
+ const re = new RegExp(`(--${k}\\s*:\\s*)([^;]+);`);
267
+ if (re.test(block)) {
268
+ const old = re.exec(block)[2].trim();
269
+ if (old !== v) changes.push(`--${k}: ${old} → ${v}`);
270
+ block = block.replace(re, `$1${v};`);
271
+ } else {
272
+ block = block.replace(/\s*$/, `\n --${k}: ${v};\n`);
273
+ changes.push(`--${k}: (new) ${v}`);
274
+ }
275
+ }
276
+ const radius = sys.radii.md ?? sys.radii.sm;
277
+ if (radius !== undefined) block = block.replace(/(--radius\s*:\s*)([^;]+);/, `$1${Math.min(radius, 9999) / 16}rem;`);
278
+ css = css.replace(root[0], `:root {${block}}`);
279
+ // Status colours need Tailwind names (bg-success, text-warning) to be usable at all.
280
+ const inline = /@theme inline\s*\{([^}]*)\}/s.exec(css);
281
+ if (inline) {
282
+ const add = ["success", "warning", "destructive"].filter((k) => vars[k] && !new RegExp(`--color-${k}\\s*:`).test(inline[1])).map((k) => ` --color-${k}: var(--${k});`);
283
+ if (add.length) css = css.replace(inline[0], inline[0].replace(/\}$/, `${add.join("\n")}\n}`));
284
+ }
285
+ if (brandPrimary) {
286
+ const fg = /--primary-foreground\s*:\s*([^;]+);/.exec(block)?.[1]?.trim();
287
+ if (fg && wcag(brandPrimary, fg) < 4.5) notes.push(`Your brand primary (${brandPrimary}) behind its button text (${fg}) is ${wcag(brandPrimary, fg).toFixed(2)}:1, under WCAG AA 4.5:1. Darken the brand for buttons or change the button text colour.`);
288
+ }
289
+ if (/\.dark\s*\{/.test(css)) notes.push("Dark-mode tokens (.dark) were left as they were; they don't follow this system yet.");
290
+ const { css: theme } = themeBlock(sys, fonts, typeSet);
291
+ const marked = `/* palate:system ${sys.id}${donor ? ` + type from ${donor.id}` : ""} — craft from ${sys.name}${donor ? ` and ${donor.name}` : ""} (DESIGN.md via VoltAgent/awesome-design-md, MIT) */\n${theme}\n/* /palate:system */`;
292
+ css = /\/\* palate:system[\s\S]*?\/\* \/palate:system \*\//.test(css) ? css.replace(/\/\* palate:system[\s\S]*?\/\* \/palate:system \*\//, marked) : `${css.trimEnd()}\n\n${marked}\n`;
293
+ for (const f of new Set([fonts.display, fonts.body, fonts.mono].filter(Boolean))) {
294
+ const imp = `@import "${FONTSOURCE(f)}";`;
295
+ if (!css.includes(imp)) css = css.replace(/(@import\s+["']tailwindcss["'];?)/, `$1\n${imp}`);
296
+ }
297
+ fs.writeFileSync(cssFile, css);
298
+ }
299
+
300
+ const { roles } = themeBlock(sys, fonts, typeSet);
301
+ const cnFile = patchCn(dir, Object.keys(roles));
302
+ const shadowsRemoved = sys.facets.elevation === "hairline" ? stripRestingShadows(dir) : 0;
303
+ if (keepBrand && !brandPrimary) notes.push(`The project had no brand colour, so the primary is ${sys.name}'s own accent. Set your own --primary in the token file, or the product will wear ${sys.name}'s colour.`);
304
+ const rules = grammar(sys, roles, Boolean(brandPrimary));
305
+ const sec = (re) => Object.entries(sys.sections).find(([k]) => re.test(k))?.[1];
306
+ const brief = [
307
+ `# Design system: ${sys.name}${donor ? ` with display type from ${donor.name}` : ""}`,
308
+ "",
309
+ `Craft transferred from ${sys.name}'s public design (DESIGN.md from VoltAgent/awesome-design-md, MIT). ${brandPrimary ? `The project's own brand colour (${brandPrimary}) is kept as the primary.` : ""} Don't reproduce ${sys.name}'s logo, wording or imagery.`,
310
+ "",
311
+ `${trim(sys.description, 600)}`,
312
+ "",
313
+ "## Type roles (use these classes, nothing else)",
314
+ "| Class | Size | Weight | Line height | Tracking |",
315
+ "|---|---|---|---|---|",
316
+ ...Object.entries(roles).map(([k, t]) => `| \`text-${k}\` | ${t.size}px | ${t.weight ?? ""} | ${t.lineHeight ?? ""} | ${t.tracking ? `${t.tracking}em` : "0"} |`),
317
+ "",
318
+ `Fonts: display \`${fonts.display}\`, body \`${fonts.body}\`${fonts.mono ? `, mono \`${fonts.mono}\`` : ""} (open substitutes where the original is proprietary). Install with: pnpm add ${[...new Set([fonts.display, fonts.body, fonts.mono].filter(Boolean))].map(FONTSOURCE).join(" ")}`,
319
+ "",
320
+ "## Rules for building anything in this system",
321
+ ...rules.map((r) => `- ${r}`),
322
+ "",
323
+ "## The system's own guidance",
324
+ sec(/do'?s and don'?ts|^do$/) ? `### Do and don't\n${trim(sec(/do'?s and don'?ts|^do$/), 1800)}` : "",
325
+ sec(/^don'?t$/) ? `### Don't\n${trim(sec(/^don'?t$/), 1200)}` : "",
326
+ sec(/elevation|depth/) ? `### Elevation\n${trim(sec(/elevation|depth/), 1200)}` : "",
327
+ sec(/whitespace|spacing system|layout/) ? `### Layout\n${trim(sec(/whitespace|spacing system|layout/), 1200)}` : "",
328
+ sec(/^buttons?$/) ? `### Buttons\n${trim(sec(/^buttons?$/), 1200)}` : "",
329
+ sec(/cards|containers/) ? `### Cards and containers\n${trim(sec(/cards|containers/), 1200)}` : "",
330
+ sec(/inputs|forms/) ? `### Inputs\n${trim(sec(/inputs|forms/), 800)}` : "",
331
+ ]
332
+ .filter((l) => l !== "")
333
+ .join("\n");
334
+ fs.mkdirSync(path.join(dir, ".palate"), { recursive: true });
335
+ fs.writeFileSync(path.join(dir, ".palate", ".gitignore"), "*\n");
336
+ fs.writeFileSync(path.join(dir, ".palate", "system.md"), brief);
337
+ const histFile = path.join(dir, ".palate", "systems.json");
338
+ const hist = fs.existsSync(histFile) ? JSON.parse(fs.readFileSync(histFile, "utf8")) : [];
339
+ hist.push({ id: sys.id, ...(donor ? { typeFrom: donor.id } : {}), at: new Date().toISOString() });
340
+ fs.writeFileSync(histFile, JSON.stringify(hist, null, 2));
341
+
342
+ return [
343
+ `Applied ${sys.name} craft to ${cssFile ? path.relative(dir, cssFile) : "(no shadcn token file found: see .palate/system.md and map the tokens by hand)"}.`,
344
+ brandPrimary ? `Kept the project's brand primary (${brandPrimary}).` : "Primary taken from the system.",
345
+ changes.length ? `Changed ${changes.length} tokens:\n${changes.map((c) => ` ${c}`).join("\n")}` : "",
346
+ `Type roles: ${Object.entries(roles).map(([k, t]) => `text-${k} ${t.size}px/${t.weight ?? ""}`).join(" · ")}`,
347
+ `Fonts: install ${[...new Set([fonts.display, fonts.body, fonts.mono].filter(Boolean))].map(FONTSOURCE).join(" ")} (imports added).`,
348
+ cnFile ? `Taught tailwind-merge the type roles in ${cnFile}, so cn() keeps them.` : "",
349
+ shadowsRemoved ? `Removed ${shadowsRemoved} resting drop shadow(s) from components/ui (this system uses hairlines).` : "",
350
+ ...notes.map((n) => `Note: ${n}`),
351
+ `Rules for extending the system: .palate/system.md (read it before building).`,
352
+ ]
353
+ .filter(Boolean)
354
+ .join("\n");
355
+ }