@palate/cli 0.0.0-stage → 0.0.2

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 +153 -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 +37 -4
  1107. package/scripts/pack-assets.mjs +58 -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
@@ -0,0 +1,698 @@
1
+ // Runs inside the page (read as text and evaluated) with { sections }. Measures the page's visual language, not
2
+ // its structure: the ground under each section, grain or paper texture, the display and body faces, the primary
3
+ // call to action and its partner, the header's pattern, how the hero is composed, how its main object is framed,
4
+ // the kind of imagery the page leans on, and how much of it carries ink. Returns raw facts and a few classes the
5
+ // DOM alone can tell; src/loop/lookvec.mjs turns colours and families into the look vector. Boxes are in page
6
+ // coordinates (the script scrolls to the top first, so a sticky header sits where it starts).
7
+ ({ sections }) => {
8
+ window.scrollTo({ top: 0, behavior: "instant" });
9
+ const docW = document.documentElement.clientWidth;
10
+ const pageH = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
11
+ const vh = innerHeight;
12
+ const SKIP = new Set(["SCRIPT", "STYLE", "NOSCRIPT", "TEMPLATE", "LINK", "META", "HEAD", "TITLE", "BR", "WBR", "SOURCE", "TRACK", "OPTION", "DATALIST"]);
13
+
14
+ // ---- colour (the same helper as page-gate.js, page-rules.js …: any computed CSS colour as [r, g, b, a])
15
+ const colourCtx = Object.assign(document.createElement("canvas"), { width: 1, height: 1 }).getContext("2d", { willReadFrequently: true });
16
+ const colourMemo = new Map();
17
+ const RGB_FN = /^rgba?\(\s*(-?[\d.]+)(%?)[,\s]+(-?[\d.]+)(%?)[,\s]+(-?[\d.]+)(%?)(?:\s*[,/]\s*([\d.]+)(%?))?\s*\)$/i;
18
+ const fromRgbFn = (m) => [1, 3, 5].map((i) => Math.max(0, Math.min(255, m[i + 1] ? (parseFloat(m[i]) * 255) / 100 : parseFloat(m[i])))).concat(m[7] === undefined ? 1 : m[8] ? parseFloat(m[7]) / 100 : parseFloat(m[7]));
19
+ const fromHex = (h) => {
20
+ const x = h.length <= 5 ? [...h.slice(1)].map((c) => c + c).join("") : h.slice(1);
21
+ return [0, 2, 4].map((i) => parseInt(x.slice(i, i + 2), 16)).concat(x.length === 8 ? parseInt(x.slice(6, 8), 16) / 255 : 1);
22
+ };
23
+ const fromSpace = (c) => {
24
+ const m = c.match(/^(oklab|oklch|lab|lch|color)\(\s*([^)]*)\)$/i);
25
+ if (!m) return null;
26
+ const [body, alpha] = m[2].split("/");
27
+ const p = body.trim().split(/[\s,]+/);
28
+ const space = m[1].toLowerCase() === "color" ? (p.shift() ?? "").toLowerCase() : m[1].toLowerCase();
29
+ const n = (s, full = 1) => (s == null || s === "none" ? 0 : s.endsWith("%") ? (parseFloat(s) / 100) * full : parseFloat(s));
30
+ const a = alpha === undefined ? 1 : n(alpha.trim());
31
+ const enc = (v) => 255 * Math.max(0, Math.min(1, v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055));
32
+ const polar = (C, h) => [C * Math.cos((h * Math.PI) / 180), C * Math.sin((h * Math.PI) / 180)];
33
+ let lin;
34
+ if (space === "oklab" || space === "oklch") {
35
+ const L = n(p[0]);
36
+ const [A, B] = space === "oklab" ? [n(p[1], 0.4), n(p[2], 0.4)] : polar(n(p[1], 0.4), n(p[2]));
37
+ const l = (L + 0.3963377774 * A + 0.2158037573 * B) ** 3, k = (L - 0.1055613458 * A - 0.0638541728 * B) ** 3, s = (L - 0.0894841775 * A - 1.291485548 * B) ** 3;
38
+ lin = [4.0767416621 * l - 3.3077115913 * k + 0.2309699292 * s, -1.2684380046 * l + 2.6097574011 * k - 0.3413193965 * s, -0.0041960863 * l - 0.7034186147 * k + 1.707614701 * s];
39
+ } else if (space === "lab" || space === "lch") {
40
+ const L = n(p[0], 100);
41
+ const [A, B] = space === "lab" ? [n(p[1], 125), n(p[2], 125)] : polar(n(p[1], 150), n(p[2]));
42
+ const fy = (L + 16) / 116, fx = fy + A / 500, fz = fy - B / 200, e = 216 / 24389, kk = 24389 / 27;
43
+ const X = 0.96422 * (fx ** 3 > e ? fx ** 3 : (116 * fx - 16) / kk), Y = L > kk * e ? fy ** 3 : L / kk, Z = 0.82521 * (fz ** 3 > e ? fz ** 3 : (116 * fz - 16) / kk);
44
+ lin = [3.1338561 * X - 1.6168667 * Y - 0.4906146 * Z, -0.9787684 * X + 1.9161415 * Y + 0.033454 * Z, 0.0719453 * X - 0.2289914 * Y + 1.4052427 * Z];
45
+ } else if (space === "srgb" || space === "display-p3" || space === "a98-rgb" || space === "rec2020") return p.slice(0, 3).map((v) => 255 * Math.max(0, Math.min(1, n(v)))).concat(a);
46
+ else if (space === "srgb-linear") lin = p.slice(0, 3).map((v) => n(v));
47
+ else return null;
48
+ return lin.map(enc).concat(a);
49
+ };
50
+ const toRgba = (c) => {
51
+ const s = String(c ?? "").trim();
52
+ if (!s || s === "none") return null;
53
+ if (colourMemo.has(s)) return colourMemo.get(s);
54
+ let v = null;
55
+ const m = s.match(RGB_FN);
56
+ if (m) v = fromRgbFn(m);
57
+ else if (/^transparent$/i.test(s)) v = [0, 0, 0, 0];
58
+ else if (/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(s)) v = fromHex(s);
59
+ else {
60
+ colourCtx.fillStyle = "#010203";
61
+ colourCtx.fillStyle = s;
62
+ const got = String(colourCtx.fillStyle);
63
+ if (got !== "#010203") {
64
+ const g = got.match(RGB_FN);
65
+ if (g) v = fromRgbFn(g);
66
+ else if (/^#[0-9a-f]{6}$/i.test(got)) v = fromHex(got);
67
+ else {
68
+ colourCtx.clearRect(0, 0, 1, 1);
69
+ colourCtx.fillRect(0, 0, 1, 1);
70
+ const d = colourCtx.getImageData(0, 0, 1, 1).data;
71
+ v = [d[0], d[1], d[2], fromSpace(got)?.[3] ?? d[3] / 255];
72
+ }
73
+ } else v = fromSpace(s);
74
+ }
75
+ colourMemo.set(s, v);
76
+ return v;
77
+ };
78
+ const colourStops = (bi) => (String(bi ?? "").match(/(?:rgba?|hsla?|oklab|oklch|lab|lch|color)\([^()]*\)|#[0-9a-f]{3,8}\b/gi) ?? []).map(toRgba).filter(Boolean);
79
+ const rgba = (c) => {
80
+ const v = toRgba(c);
81
+ return v && v[3] >= 3 / 255 ? v : null;
82
+ };
83
+ const hex = (rgb) => (rgb ? "#" + rgb.slice(0, 3).map((v) => Math.round(v).toString(16).padStart(2, "0")).join("") : null);
84
+ const dist = (a, b) => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
85
+ const over = (top, under) => [0, 1, 2].map((i) => top[i] * top[3] + under[i] * (1 - top[3]));
86
+ const bgMemo = new Map();
87
+ // The colour painted behind an element: its own background and its ancestors', composited (gradients count by
88
+ // their average stop, so a page painted with a soft gradient still has a ground).
89
+ const ownBg = (cs) => {
90
+ const c = rgba(cs.backgroundColor);
91
+ if (c && c[3] >= 0.5) return c;
92
+ const stops = cs.backgroundImage && cs.backgroundImage !== "none" && !/url\(/.test(cs.backgroundImage) ? colourStops(cs.backgroundImage).filter((s) => s[3] >= 0.9) : [];
93
+ if (stops.length >= 2) return [0, 1, 2].map((i) => stops.reduce((x, s) => x + s[i], 0) / stops.length).concat(1);
94
+ return c;
95
+ };
96
+ const paintedBg = (el) => {
97
+ if (!el || el.nodeType !== 1) return [255, 255, 255];
98
+ if (bgMemo.has(el)) return bgMemo.get(el);
99
+ const own = ownBg(getComputedStyle(el));
100
+ const out = own && own[3] >= 0.98 ? own.slice(0, 3) : own ? over(own, paintedBg(el.parentElement)) : paintedBg(el.parentElement);
101
+ bgMemo.set(el, out);
102
+ return out;
103
+ };
104
+ const visMemo = new Map();
105
+ const shown = (el) => {
106
+ if (!el || el.nodeType !== 1 || el === document.documentElement) return true;
107
+ if (visMemo.has(el)) return visMemo.get(el);
108
+ const cs = getComputedStyle(el);
109
+ const v = cs.display !== "none" && cs.visibility !== "hidden" && parseFloat(cs.opacity) > 0.05 && shown(el.parentElement);
110
+ visMemo.set(el, v);
111
+ return v;
112
+ };
113
+ const pbox = (r) => ({ x: r.left + scrollX, y: r.top + scrollY, w: r.width, h: r.height });
114
+ const boxOf = (el) => pbox(el.getBoundingClientRect());
115
+ const area = (b) => Math.max(0, b.w) * Math.max(0, b.h);
116
+ const inter = (a, b) => Math.max(0, Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x)) * Math.max(0, Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y));
117
+ const clean = (s) => (s ?? "").replace(/\s+/g, " ").trim();
118
+ // Box shadows, layer by layer (Tailwind writes transparent "0 0 0 0" layers before the real one): a soft
119
+ // shadow (blur or offset, not inset) and a ring (0 blur, a spread, no offset: a border drawn as a shadow).
120
+ const shadowLayers = (v) => {
121
+ if (!v || v === "none") return [];
122
+ const out = [];
123
+ let depth = 0, cur = "";
124
+ for (const ch of v + ",") {
125
+ if (ch === "(") depth++;
126
+ if (ch === ")") depth--;
127
+ if (ch === "," && depth === 0) {
128
+ const t = cur.trim();
129
+ cur = "";
130
+ if (!t) continue;
131
+ const colour = (t.match(/(?:rgba?|hsla?|oklab|oklch|lab|lch|color)\([^()]*\)|#[0-9a-f]{3,8}(?![0-9a-f])/i) ?? [])[0];
132
+ const nums = t.replace(colour ?? "", "").match(/-?[\d.]+px|(?<![\d.])0(?![\d.])/g) ?? [];
133
+ const [x, y, blur, spread] = nums.map((n) => parseFloat(n)).concat([0, 0, 0, 0]);
134
+ out.push({ alpha: colour ? toRgba(colour)?.[3] ?? 1 : 1, x, y, blur, spread, inset: /inset/.test(t) });
135
+ } else cur += ch;
136
+ }
137
+ return out;
138
+ };
139
+ const shadowOf = (cs) => shadowLayers(cs.boxShadow).some((l) => !l.inset && l.alpha >= 0.03 && (l.blur >= 2 || Math.abs(l.y) >= 2));
140
+ const ringOf = (cs) => shadowLayers(cs.boxShadow).some((l) => l.alpha >= 0.05 && l.blur < 1 && l.spread >= 0.5 && !l.x && !l.y);
141
+ const borderSides = (el, cs) => {
142
+ const under = paintedBg(el.parentElement);
143
+ let n = 0;
144
+ for (const side of ["Top", "Right", "Bottom", "Left"]) {
145
+ if (!(parseFloat(cs[`border${side}Width`]) >= 0.5) || /none|hidden/.test(cs[`border${side}Style`])) continue;
146
+ const c = rgba(cs[`border${side}Color`]);
147
+ if (c && c[3] >= 0.12 && dist(over(c, under), under) >= 9) n++;
148
+ }
149
+ return n || (ringOf(cs) ? 4 : 0);
150
+ };
151
+ const firstScreen = { x: 0, y: 0, w: docW, h: vh };
152
+
153
+ // ---- everything visible, once
154
+ const els = [];
155
+ for (const el of document.body.querySelectorAll("*")) {
156
+ if (SKIP.has(el.tagName) || el.parentElement?.closest("svg")) continue;
157
+ const r = el.getBoundingClientRect();
158
+ if (r.width < 1 || r.height < 1 || r.right < 0 || r.left > docW) continue;
159
+ if (!shown(el)) continue;
160
+ els.push({ el, b: pbox(r), cs: getComputedStyle(el), tag: el.tagName.toLowerCase() });
161
+ }
162
+
163
+ // ---- media: images, video, canvas, big svg, background images (texture told apart from pictures)
164
+ const TEXTURE_URL = /noise|grain|paper|texture|turbulence|fractalnoise|fibre|fiber|speckle|dither/i;
165
+ const media = [];
166
+ let texture = false;
167
+ const textureWhy = [];
168
+ const SVG_URL = /\.svg(\?|#|$)|^data:image\/svg/i;
169
+ const noisy = (url) => {
170
+ let d = url;
171
+ try {
172
+ d = decodeURIComponent(url);
173
+ } catch {}
174
+ return TEXTURE_URL.test(url) || /feTurbulence/i.test(d.slice(0, 8000));
175
+ };
176
+ const bigOver = (b, share) => b.w >= 0.3 * docW && b.h >= 0.3 * vh && area(b) >= share * docW * vh;
177
+ for (const { el, b, cs, tag } of els) {
178
+ if (["img", "video", "canvas", "picture", "iframe"].includes(tag) || (tag === "svg" && b.w >= 120 && b.h >= 90)) {
179
+ if (tag === "picture") continue;
180
+ if (b.w * b.h < 6000) continue;
181
+ const src = tag === "img" ? el.currentSrc || el.src || "" : "";
182
+ const kind = tag === "svg" || /\.svg(\?|$)|^data:image\/svg/i.test(src) ? "illustration" : tag === "canvas" ? "canvas" : tag === "iframe" ? "embed" : "photo";
183
+ const op = parseFloat(cs.opacity);
184
+ // A grain layer drawn as an image (a tiled noise PNG, an SVG of feTurbulence over the page).
185
+ if ((TEXTURE_URL.test(src) || (tag === "svg" && el.querySelector("feTurbulence"))) && bigOver(b, 0.15)) {
186
+ texture = true;
187
+ textureWhy.push(`${tag} ${TEXTURE_URL.test(src) ? src.split("/").pop().slice(0, 40) : "feTurbulence"}`);
188
+ continue;
189
+ }
190
+ if (op < 0.2) continue;
191
+ media.push({ b, kind, tag, alt: el.getAttribute?.("alt") ?? "", src: src.slice(0, 120), el });
192
+ continue;
193
+ }
194
+ const layers = [[cs, b, el === document.body]];
195
+ for (const pseudo of ["::before", "::after"]) {
196
+ const ps = getComputedStyle(el, pseudo);
197
+ if (!ps.content || ps.content === "none" || ps.content === "normal" || ps.display === "none") continue;
198
+ const w = parseFloat(ps.width), h = parseFloat(ps.height);
199
+ const pb = Number.isFinite(w) && Number.isFinite(h) && w > 0 && h > 0 ? { x: b.x, y: b.y, w: Math.min(w, docW), h } : b;
200
+ layers.push([ps, pb, true]);
201
+ }
202
+ for (const [s, lb, overlay] of layers) {
203
+ const bi = s.backgroundImage;
204
+ const filt = String(s.filter ?? "") + String(s.backdropFilter ?? "");
205
+ if (/url\(/.test(filt) && bigOver(lb, 0.15)) {
206
+ texture = true;
207
+ textureWhy.push(`${tag} filter`);
208
+ }
209
+ if (!bi || bi === "none" || !/url\(/.test(bi)) continue;
210
+ const url = (bi.match(/url\("?([^")]*)"?\)/) ?? [])[1] ?? "";
211
+ const tiled = !/no-repeat/.test(s.backgroundRepeat) && /^\d/.test(s.backgroundSize) && parseFloat(s.backgroundSize) <= 600;
212
+ const faint = parseFloat(s.opacity) < 0.6 || (s.mixBlendMode && s.mixBlendMode !== "normal");
213
+ // Grain: named so (noise, paper, grain …), an SVG of feTurbulence, or a tiled or faint raster overlay. An SVG
214
+ // tile without noise is a pattern (dots, a grid), not grain, and not imagery either.
215
+ const svgUrl = SVG_URL.test(url);
216
+ const isTexture = noisy(url) || (!svgUrl && ((tiled && (overlay || lb.w * lb.h >= 0.3 * docW * vh)) || (overlay && faint)));
217
+ if (!isTexture && svgUrl && tiled) continue;
218
+ if (isTexture) {
219
+ if (bigOver(lb, 0.1) || el === document.body || el === document.documentElement) {
220
+ texture = true;
221
+ textureWhy.push(`${tag}${s === cs ? "" : " pseudo"} ${url.slice(0, 50)}`);
222
+ }
223
+ continue;
224
+ }
225
+ if (lb.w * lb.h >= 6000) media.push({ b: lb, kind: /\.svg(\?|$)|^data:image\/svg/i.test(url) ? "illustration" : "photo", tag: "background-image", src: url.slice(0, 120), el });
226
+ }
227
+ }
228
+ // The root's own background image (body/html are not in els' pseudo pass when html carries it).
229
+ for (const [root, pseudo] of [document.documentElement, document.body].flatMap((r) => [[r, null], [r, "::before"], [r, "::after"]])) {
230
+ const cs = getComputedStyle(root, pseudo);
231
+ if (pseudo && (!cs.content || cs.content === "none" || cs.content === "normal" || cs.display === "none")) continue;
232
+ const url = (cs.backgroundImage.match(/url\("?([^")]*)"?\)/) ?? [])[1] ?? "";
233
+ if (url && (noisy(url) || !SVG_URL.test(url))) {
234
+ texture = true;
235
+ textureWhy.push(`${root.tagName.toLowerCase()} background`);
236
+ }
237
+ }
238
+ if (!texture && document.querySelector("feTurbulence")) {
239
+ const f = document.querySelector("feTurbulence").closest("filter");
240
+ if (f?.id && els.some(({ cs, b }) => String(cs.filter).includes(f.id) && bigOver(b, 0.1))) {
241
+ texture = true;
242
+ textureWhy.push("feTurbulence filter");
243
+ }
244
+ }
245
+
246
+ // ---- section grounds: the deepest element that covers most of a section and paints an opaque ground
247
+ const sectionEls = sections.map((s) => {
248
+ try {
249
+ return document.querySelector(s.selector);
250
+ } catch {
251
+ return null;
252
+ }
253
+ });
254
+ const rootBg = paintedBg(document.body);
255
+ const photoIn = (b, share) => media.filter((m) => m.kind === "photo" && m.b.w >= 0.85 * docW && inter(m.b, b) >= share * area(b));
256
+ const bands = sections.map((s, i) => {
257
+ const sb = { x: 0, y: s.box.y, w: docW, h: s.box.height };
258
+ let best = sectionEls[i] ?? null;
259
+ let bg = best ? paintedBg(best) : rootBg;
260
+ // A full-width child that covers most of the section with its own ground (a coloured inner panel).
261
+ for (const { el, b, cs } of els) {
262
+ if (b.y > sb.y + sb.h || b.y + b.h < sb.y) continue;
263
+ if (inter(b, sb) < 0.7 * area(sb) || b.w < 0.9 * docW) continue;
264
+ const own = ownBg(cs);
265
+ if (own && own[3] >= 0.6 && (!best || best.contains(el) || !el.contains(best))) {
266
+ bg = paintedBg(el);
267
+ best = el;
268
+ }
269
+ }
270
+ const photo = photoIn(sb, 0.6).length > 0;
271
+ return { y: Math.round(sb.y), h: Math.round(sb.h), name: s.name, bg: hex(bg), photo };
272
+ });
273
+
274
+ // ---- the header: a band at the top with links
275
+ const navLinks = (root) =>
276
+ [...root.querySelectorAll("a, button, [role=button]")].filter((a) => {
277
+ if (!shown(a)) return false;
278
+ const r = a.getBoundingClientRect();
279
+ return r.width >= 8 && r.height >= 8 && r.top < 200 && clean(a.textContent || a.getAttribute("aria-label")).length <= 40;
280
+ });
281
+ let headerEl = [...document.querySelectorAll("header, [role=banner], nav")].map((el) => ({ el, r: el.getBoundingClientRect() })).filter(({ el, r }) => shown(el) && r.top < 140 && r.height > 20 && r.height < 0.4 * vh && r.width > 0.4 * docW && navLinks(el).length >= 1).sort((a, b) => a.r.top - b.r.top || b.r.width - a.r.width)[0]?.el ?? null;
282
+ // No landmark (a floating bar of divs, a narrow <nav>): the smallest element that holds the links along the top.
283
+ if (!headerEl) {
284
+ const top = navLinks(document.body).filter((a) => a.getBoundingClientRect().top < 120);
285
+ if (top.length >= 2) {
286
+ let lca = top[0].parentElement;
287
+ while (lca && lca !== document.body && !top.every((a) => lca.contains(a))) lca = lca.parentElement;
288
+ const r = lca?.getBoundingClientRect();
289
+ if (lca && lca !== document.body && r.height < 0.4 * vh) headerEl = lca;
290
+ }
291
+ }
292
+ // A vertical side bar: fixed or sticky, at the left or right edge, most of the screen tall, narrow.
293
+ const side = els.find(({ cs, b, el }) => /fixed|sticky/.test(cs.position) && b.h >= 0.7 * vh && b.w <= 340 && (b.x <= 4 || b.x + b.w >= docW - 4) && navLinks(el).length >= 3);
294
+ let header = { pattern: "none", cta: "none", logo: null, links: 0 };
295
+ const btnStyle = (el) => {
296
+ if (!el) return null;
297
+ const cs = getComputedStyle(el);
298
+ const r = el.getBoundingClientRect();
299
+ const under = paintedBg(el.parentElement);
300
+ const own = rgba(cs.backgroundColor);
301
+ const grad = cs.backgroundImage && cs.backgroundImage !== "none" && !/url\(/.test(cs.backgroundImage) && colourStops(cs.backgroundImage).length >= 2;
302
+ const radius = parseFloat(cs.borderTopLeftRadius) || 0;
303
+ const shape = radius >= r.height / 2 - 1.5 ? "pill" : radius <= 3 ? "square" : "rounded";
304
+ let style;
305
+ const stops = grad ? colourStops(cs.backgroundImage).filter((c) => c[3] >= 0.9) : [];
306
+ // A gradient is a CTA's look only when its ends differ clearly (not a sheen of one colour over itself).
307
+ const hueOf = (c) => Math.atan2(Math.sqrt(3) * (c[1] - c[2]), 2 * c[0] - c[1] - c[2]) * (180 / Math.PI);
308
+ const ends = stops.length >= 2 ? [stops[0], stops[stops.length - 1]] : null;
309
+ const fillRgb = own && own[3] >= 0.5 ? over(own, under) : stops.length ? stops[0] : null;
310
+ const fillDist = fillRgb ? dist(fillRgb, under) : 0;
311
+ const ringed = borderSides(el, cs) >= 3;
312
+ if (ends && (dist(ends[0], ends[1]) > 70 || (Math.min(Math.abs(hueOf(ends[0]) - hueOf(ends[1])), 360 - Math.abs(hueOf(ends[0]) - hueOf(ends[1]))) > 40 && dist(ends[0], ends[1]) > 30))) style = "gradient";
313
+ else if (fillDist > 45) style = `solid-${shape}`;
314
+ else if (ringed || (fillDist > 0 && shadowOf(cs))) style = "outline";
315
+ else if (fillDist > 18) style = `solid-${shape}`;
316
+ else {
317
+ const underline = /underline/.test(cs.textDecorationLine) || (parseFloat(cs.borderBottomWidth) >= 1 && !/none/.test(cs.borderBottomStyle));
318
+ style = underline ? "text-link-underlined" : "text-link";
319
+ }
320
+ const fill = style.startsWith("solid") || style === "gradient" ? (fillRgb ? fillRgb.slice(0, 3) : null) : style === "outline" ? rgba(cs.borderTopColor)?.slice(0, 3) ?? null : rgba(cs.color)?.slice(0, 3) ?? null;
321
+ return { style, shape, fill: hex(fill), text: clean(el.textContent).slice(0, 40), box: pbox(r), radius: Math.round(radius) };
322
+ };
323
+ if (side) header = { pattern: "side", cta: "none", logo: null, links: navLinks(side.el).length };
324
+ else if (headerEl) {
325
+ // Widen to the band the nav sits in (a <nav> inside a header wrapper).
326
+ while (headerEl.parentElement && headerEl.parentElement !== document.body && headerEl.parentElement.getBoundingClientRect().height < 0.6 * vh && headerEl.parentElement.getBoundingClientRect().top < 140 && navLinks(headerEl.parentElement).length > navLinks(headerEl).length) headerEl = headerEl.parentElement;
327
+ const hr = headerEl.getBoundingClientRect();
328
+ const links = navLinks(headerEl).filter((a) => !a.parentElement.closest("[hidden]"));
329
+ const logoEl = headerEl.querySelector('a[href="/"], a[href="./"], a[href="#top"], a[href="#"], [class*=logo i], [class*=brand i], [aria-label*=home i], [class*=wordmark i]') ?? links.slice().sort((a, b) => a.getBoundingClientRect().left - b.getBoundingClientRect().left)[0] ?? null;
330
+ const lr = logoEl?.getBoundingClientRect();
331
+ const others = links.filter((a) => a !== logoEl && !logoEl?.contains(a) && !a.contains(logoEl));
332
+ const styles = others.map((a) => ({ a, s: btnStyle(a), r: a.getBoundingClientRect() }));
333
+ const ctaCand = styles.filter((x) => !x.s.style.startsWith("text-link")).sort((a, b) => b.r.right - a.r.right)[0] ?? null;
334
+ const plain = styles.filter((x) => x !== ctaCand);
335
+ const mid = docW / 2;
336
+ const logoCentred = lr && Math.abs(lr.left + lr.width / 2 - mid) < 0.08 * docW;
337
+ const leftLinks = plain.filter((x) => x.r.right < mid - 40).length, rightLinks = plain.filter((x) => x.r.left > mid + 40).length;
338
+ let pattern;
339
+ if (logoCentred && leftLinks >= 1 && rightLinks >= 1) pattern = "split";
340
+ else if (logoCentred) pattern = "centred-wordmark";
341
+ else if (plain.length >= 2) pattern = "logo-left-nav-cta";
342
+ else pattern = "logo-cta";
343
+ // Over an image: the header has no ground of its own and a full-bleed picture sits under it.
344
+ const hcs = getComputedStyle(headerEl);
345
+ const ownH = rgba(hcs.backgroundColor);
346
+ const hb = pbox(hr);
347
+ if ((!ownH || ownH[3] < 0.5) && photoIn({ x: 0, y: hb.y, w: docW, h: Math.max(hb.h, 40) }, 0.8).length) pattern = "overlay";
348
+ const ctaStyle = ctaCand ? (ctaCand.s.style === "outline" && ctaCand.s.shape === "pill" ? "outline-pill" : ctaCand.s.style) : others.length ? "text-link" : "none";
349
+ header = { pattern, cta: ctaStyle, ctaText: ctaCand?.s.text ?? null, logo: lr ? { x: Math.round(lr.left), w: Math.round(lr.width), text: clean(logoEl.textContent).slice(0, 30) } : null, links: plain.length, height: Math.round(hr.height), bottom: Math.round(hb.y + hb.h) };
350
+ } else {
351
+ const top = navLinks(document.body).filter((a) => a.getBoundingClientRect().top < 120);
352
+ if (top.length >= 2) header = { pattern: "logo-left-nav-cta", cta: "text-link", logo: null, links: top.length, bottom: 100 };
353
+ }
354
+ const headerBottom = header.bottom ?? (side ? 0 : 0);
355
+
356
+ // ---- type: the headline and the body face
357
+ const texts = [];
358
+ const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
359
+ const range = document.createRange();
360
+ for (let n = walker.nextNode(); n; n = walker.nextNode()) {
361
+ const t = n.data;
362
+ if (!t || !t.trim()) continue;
363
+ const p = n.parentElement;
364
+ if (!p || SKIP.has(p.tagName) || p.closest("svg, script, style, noscript, template, select, textarea, code, pre")) continue;
365
+ if (!shown(p)) continue;
366
+ const cs = getComputedStyle(p);
367
+ const col = rgba(cs.color);
368
+ if (!col || col[3] < 0.1) continue;
369
+ range.selectNodeContents(n);
370
+ const rects = [...range.getClientRects()].filter((r) => r.width >= 1 && r.height >= 1).map(pbox);
371
+ if (!rects.length) continue;
372
+ texts.push({ el: p, text: t, rects, cs, size: parseFloat(cs.fontSize) });
373
+ }
374
+ const inFirst = (b) => b.y < vh && b.y + b.h > Math.max(0, headerBottom - 4) && b.x < docW && b.x + b.w > 0;
375
+ const h1 = [...document.querySelectorAll("h1")].find((h) => shown(h) && inFirst(boxOf(h)) && clean(h.textContent).length > 1);
376
+ let headEl = h1 ?? null;
377
+ if (!headEl) {
378
+ const big = texts.filter((t) => t.rects.some(inFirst) && !(headerEl && headerEl.contains(t.el))).sort((a, b) => b.size - a.size)[0];
379
+ headEl = big?.el ?? null;
380
+ }
381
+ // The headline's own text style: its largest text node (a headline with one word in a span keeps its face).
382
+ let display = null;
383
+ if (headEl) {
384
+ const own = texts.filter((t) => headEl.contains(t.el)).sort((a, b) => b.size * b.text.length - a.size * a.text.length)[0];
385
+ const cs = own?.cs ?? getComputedStyle(headEl);
386
+ const size = parseFloat(cs.fontSize);
387
+ const txt = clean(headEl.textContent);
388
+ const letters = txt.replace(/[^A-Za-zÀ-ÿ]/g, "");
389
+ const ls = cs.letterSpacing === "normal" ? 0 : parseFloat(cs.letterSpacing) / size;
390
+ display = {
391
+ family: cs.fontFamily,
392
+ weight: Number(cs.fontWeight) || 400,
393
+ upper: cs.textTransform === "uppercase" || (letters.length >= 3 && letters === letters.toUpperCase()),
394
+ italic: /italic|oblique/.test(cs.fontStyle),
395
+ size: Math.round(size),
396
+ tracking: +ls.toFixed(3),
397
+ align: getComputedStyle(headEl).textAlign,
398
+ text: txt.slice(0, 80),
399
+ box: boxOf(headEl),
400
+ colour: hex(rgba(cs.color)),
401
+ };
402
+ }
403
+ // Body: the family that sets the most characters of running text (paragraph-sized, outside headings and nav).
404
+ const bodyFam = new Map();
405
+ for (const t of texts) {
406
+ if (t.size < 13 || t.size > 24 || t.el.closest("h1, h2, h3, nav, footer, button, a[role=button], code, pre") || (headerEl && headerEl.contains(t.el))) continue;
407
+ if (t.text.trim().length < 20) continue;
408
+ bodyFam.set(t.cs.fontFamily, (bodyFam.get(t.cs.fontFamily) ?? 0) + t.text.length);
409
+ }
410
+ const body = [...bodyFam.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] ?? getComputedStyle(document.body).fontFamily;
411
+
412
+ // ---- the hero: the first section below the header, measured on the first screen
413
+ const heroSec = sections.find((s) => s.box.y + s.box.height > headerBottom + 20 && !/^(header|nav)$/i.test(s.tag ?? "") && s.name !== "Navigation") ?? sections[0];
414
+ const heroBox = heroSec ? { x: 0, y: Math.max(heroSec.box.y, headerBottom), w: docW, h: Math.min(heroSec.box.height, vh * 1.1) } : { x: 0, y: headerBottom, w: docW, h: vh };
415
+ const fold = { x: 0, y: headerBottom, w: docW, h: Math.max(200, vh - headerBottom) };
416
+ // Primary action: buttons and button-like links in the first screen, outside the header.
417
+ const actions = [...document.querySelectorAll("a, button, [role=button], input[type=submit]")]
418
+ .filter((a) => shown(a) && !(headerEl && headerEl.contains(a)) && !(side && side.el.contains(a)))
419
+ .map((a) => ({ a, r: a.getBoundingClientRect() }))
420
+ .filter(({ r }) => r.width >= 40 && r.width <= 520 && r.height >= 14 && r.height <= 96 && r.top < vh - 10 && r.top + scrollY >= headerBottom - 4)
421
+ .map(({ a }) => ({ a, s: btnStyle(a) }))
422
+ .filter((x) => x.s.text.length >= 2);
423
+ const rank = (s) => (s.style === "gradient" || s.style.startsWith("solid") ? 3 : s.style === "outline" ? 2 : 1);
424
+
425
+ // The hero's object: the biggest picture or framed surface in the first screen that doesn't hold the headline.
426
+ const holdsHead = (el) => headEl && (el.contains(headEl) || headEl.contains(el));
427
+ const objects = [];
428
+ for (const m of media) {
429
+ const vis = inter(m.b, fold);
430
+ if (vis < 0.03 * area(fold)) continue;
431
+ // A picture behind the headline (a glow, a wash, a full-bleed photo) is the hero's backdrop, not its object.
432
+ if (display && inter(m.b, display.box) >= 0.7 * area(display.box)) continue;
433
+ objects.push({ b: m.b, kind: m.kind, el: m.el, vis, media: true });
434
+ }
435
+ for (const { el, b, cs } of els) {
436
+ if (b.w < 240 || b.h < 160 || b.w > 0.97 * docW || holdsHead(el)) continue;
437
+ const vis = inter(b, fold);
438
+ if (vis < 0.05 * area(fold)) continue;
439
+ const own = rgba(cs.backgroundColor);
440
+ const under = paintedBg(el.parentElement);
441
+ const ground = own && own[3] > 0.3 && dist(over(own, under), under) > 6;
442
+ const shadow = shadowOf(cs);
443
+ const sides = borderSides(el, cs);
444
+ if (!ground && !shadow && sides < 3) continue;
445
+ // A section's wrapper or the hero's own panel holding the whole text column isn't the object.
446
+ if (actions.some((x) => el.contains(x.a)) && texts.some((t) => el.contains(t.el) && t.size >= 28)) continue;
447
+ objects.push({ b, kind: "surface", el, vis, media: false, shadow, sides, ground });
448
+ }
449
+ // Prefer the outermost frame of the biggest thing: a card that holds the screenshot is the object.
450
+ objects.sort((a, b) => b.vis - a.vis);
451
+ let object = objects[0] ?? null;
452
+ if (object) {
453
+ const outer = objects.find((o) => o !== object && !o.media && o.el.contains(object.el) && area(o.b) <= 2.2 * area(object.b));
454
+ if (outer) object = outer;
455
+ }
456
+ // The primary action: a button-like control outside the hero's object (a row in a product mock isn't the
457
+ // page's CTA), strongest style first, then the one nearest the headline.
458
+ const nearHead = (b) => (display ? Math.hypot(Math.max(0, b.x - (display.box.x + display.box.w), display.box.x - b.x - b.w), Math.max(0, b.y - (display.box.y + display.box.h), display.box.y - b.y - b.h)) : b.y);
459
+ const outside = actions.filter((x) => !(object && object.el.contains(x.a)));
460
+ const pool = outside.length ? outside : actions;
461
+ const primary = pool.slice().sort((x, y) => rank(y.s) - rank(x.s) || nearHead(x.s.box) - nearHead(y.s.box))[0] ?? null;
462
+ let secondary = "none";
463
+ if (primary) {
464
+ const near = pool.filter((x) => x !== primary && Math.abs(x.s.box.y + x.s.box.h / 2 - (primary.s.box.y + primary.s.box.h / 2)) < 50 && Math.abs(x.s.box.x - primary.s.box.x) < 520)[0];
465
+ if (near) secondary = near.s.style === "text-link-underlined" ? "underlined-link" : near.s.style === "text-link" ? "text-link" : near.s.style === "outline" ? "ghost" : "solid";
466
+ }
467
+ // The buttons' anatomy, beyond fill and shape: two pages with the same 48px solid box, the same semi-bold
468
+ // sentence-case label and the same underlined link beside it share a button whatever their colours.
469
+ const lumOf = (rgb) => {
470
+ const f = (v) => {
471
+ const c = v / 255;
472
+ return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
473
+ };
474
+ return 0.2126 * f(rgb[0]) + 0.7152 * f(rgb[1]) + 0.0722 * f(rgb[2]);
475
+ };
476
+ const ratioOf = (a, b) => {
477
+ const [x, y] = [lumOf(a), lumOf(b)].sort((p, q) => q - p);
478
+ return (x + 0.05) / (y + 0.05);
479
+ };
480
+ const anatomy = (el, s) => {
481
+ if (!el || !s) return null;
482
+ const cs = getComputedStyle(el);
483
+ const r = el.getBoundingClientRect();
484
+ const inside = texts.filter((t) => el.contains(t.el));
485
+ const main = inside.slice().sort((a, b) => b.text.trim().length * b.size - a.text.trim().length * a.size)[0] ?? null;
486
+ const codeEl = main ? null : el.querySelector("code, samp, kbd");
487
+ const lcs = main?.cs ?? (codeEl ? getComputedStyle(codeEl) : cs);
488
+ const px = parseFloat(lcs.fontSize) || 16;
489
+ const txt = clean(el.textContent);
490
+ const letters = clean(main?.text ?? txt).replace(/[^A-Za-zÀ-ÿ]/g, "");
491
+ const upper = lcs.textTransform === "uppercase" || (letters.length >= 3 && letters === letters.toUpperCase());
492
+ const tracking = lcs.letterSpacing === "normal" ? 0 : parseFloat(lcs.letterSpacing) / px;
493
+ const under = paintedBg(el.parentElement);
494
+ const own = rgba(cs.backgroundColor);
495
+ const boxed = s.style.startsWith("solid") || s.style === "gradient";
496
+ const fillRgb = boxed ? (own && own[3] >= 0.5 ? over(own, under) : colourStops(cs.backgroundImage).filter((c) => c[3] >= 0.9)[0]?.slice(0, 3) ?? null) : null;
497
+ // Underlined: on the control, on its label, or a bottom border standing in for one.
498
+ let underline = /underline/.test(cs.textDecorationLine) || (parseFloat(cs.borderBottomWidth) >= 1 && !/none/.test(cs.borderBottomStyle) && !(parseFloat(cs.borderTopWidth) >= 1));
499
+ for (let e = main?.el; e && e !== el.parentElement && !underline; e = e.parentElement) if (/underline/.test(getComputedStyle(e).textDecorationLine)) underline = true;
500
+ let fill;
501
+ if (boxed) fill = fillRgb && ratioOf(fillRgb, under) < 1.45 && dist(fillRgb, under) < 90 ? "tinted" : "solid";
502
+ else if (s.style === "outline") fill = "outline";
503
+ else fill = underline || s.style === "text-link-underlined" ? "underline" : "ghost";
504
+ const labelRgb = rgba(lcs.color)?.slice(0, 3) ?? null;
505
+ // Adornments: a keycap, a detail (a price, a day, a number after a separator), an arrow or an icon.
506
+ const pr = (n) => pbox(n.getBoundingClientRect());
507
+ const icons = [...el.querySelectorAll("svg, img, i, [class*=icon i]")].filter((i) => {
508
+ const b = i.getBoundingClientRect();
509
+ return shown(i) && b.width >= 6 && b.width <= 40 && b.height <= 40 && !(i.parentElement?.closest("svg"));
510
+ });
511
+ const key = [...el.querySelectorAll("kbd, [class*=kbd i], [class*=keycap i], [class*=shortcut i]")].find((k) => shown(k));
512
+ const DETAIL = /[£$€¥₹]\s?\d|\d\s?(?:€|kr\b|zł)|[·|•—–]\s*[^·|•—–]*\d/;
513
+ const detailKid = [...el.children].some((k) => k !== main?.el && /\d/.test(k.textContent ?? "") && clean(k.textContent).length <= 16 && clean(k.textContent) !== txt);
514
+ let adornment = "none";
515
+ if (key) adornment = "keycap";
516
+ else if (DETAIL.test(txt) || detailKid) adornment = "detail";
517
+ else if (/[→↗↘›»➝➜⟶⇢]|->/.test(txt)) adornment = "arrow";
518
+ else if (icons.length) {
519
+ const ib = pr(icons[0]);
520
+ const tb = main?.rects?.[0] ?? null;
521
+ adornment = tb && ib.x + ib.w / 2 < tb.x ? "icon" : "arrow";
522
+ }
523
+ return {
524
+ h: Math.round(r.height),
525
+ w: Math.round(r.width),
526
+ radius: Math.round(parseFloat(cs.borderTopLeftRadius) || 0),
527
+ px: Math.round(px * 10) / 10,
528
+ weight: Number(lcs.fontWeight) || 400,
529
+ family: lcs.fontFamily,
530
+ upper,
531
+ tracking: +tracking.toFixed(3),
532
+ underline,
533
+ fill,
534
+ fillHex: hex(fillRgb),
535
+ labelHex: hex(labelRgb),
536
+ contrast: labelRgb ? +ratioOf(labelRgb, fillRgb ?? under).toFixed(2) : null,
537
+ adornment,
538
+ // Its edge: a ring (a 1px border or a 0-blur shadow), a soft shadow under it, both, or nothing.
539
+ edge: [borderSides(el, cs) >= 3 ? "ring" : null, shadowOf(cs) ? "shadow" : null].filter(Boolean).join("+") || "none",
540
+ text: txt.slice(0, 40),
541
+ };
542
+ };
543
+ let buttons = null;
544
+ if (primary) {
545
+ const nearEl = pool.filter((x) => x !== primary && Math.abs(x.s.box.y + x.s.box.h / 2 - (primary.s.box.y + primary.s.box.h / 2)) < 50 && Math.abs(x.s.box.x - primary.s.box.x) < 520)[0] ?? null;
546
+ buttons = { primary: anatomy(primary.a, primary.s), secondary: nearEl ? anatomy(nearEl.a, nearEl.s) : null, secondaryStyle: secondary };
547
+ }
548
+ const bleedPhoto = media.find((m) => (m.kind === "photo" || m.kind === "canvas") && m.b.w >= 0.9 * docW && inter(m.b, firstScreen) >= 0.5 * area(firstScreen));
549
+ // The ground is a photo only when a picture (not a drawn canvas) covers most of the first screen.
550
+ const groundPhoto = media.find((m) => m.kind === "photo" && m.b.w >= 0.9 * docW && inter(m.b, firstScreen) >= 0.5 * area(firstScreen));
551
+ const hb = display?.box ?? null;
552
+ const cx = (b) => b.x + b.w / 2;
553
+ let hero = "centred";
554
+ const galleryItems = media.filter((m) => inter(m.b, fold) >= 0.04 * area(fold) && m.b.w < 0.6 * docW);
555
+ // Text columns in the hero: paragraph blocks that sit side by side.
556
+ const paras = [...document.querySelectorAll("p")].filter((p) => shown(p) && inFirst(boxOf(p)) && clean(p.textContent).length > 40).map(boxOf);
557
+ const colXs = [...new Set(paras.map((b) => Math.round(b.x / 120)))];
558
+ if (bleedPhoto) hero = "full-bleed";
559
+ else if (galleryItems.length >= 3 && !galleryItems.some((m) => area(m.b) > 0.3 * area(fold))) hero = "gallery";
560
+ else if (hb && object) {
561
+ const tx = cx(hb), ox = cx(object.b);
562
+ const objShare = inter(object.b, fold) / area(fold);
563
+ if (object.b.w < 0.75 * docW && tx < 0.48 * docW && ox > 0.52 * docW && object.b.x >= hb.x + hb.w * 0.5) hero = "split";
564
+ else if (object.b.w < 0.75 * docW && tx > 0.52 * docW && ox < 0.48 * docW) hero = "split-reversed";
565
+ else if (object.b.y < hb.y - 20 || (objShare >= 0.4 && (display?.size ?? 0) <= 56)) hero = "object-first";
566
+ else if (object.b.w >= 0.75 * docW && object.b.y > hb.y && objShare >= 0.45 && (display?.size ?? 0) <= 64) hero = "object-first";
567
+ else if (Math.abs(tx - docW / 2) < 0.1 * docW) hero = "centred";
568
+ else if (object.b.y >= hb.y + hb.h) hero = Math.abs(tx - docW / 2) < 0.1 * docW ? "centred" : "type-only";
569
+ else hero = "split";
570
+ } else if (hb) {
571
+ if (colXs.length >= 3) hero = "editorial";
572
+ else if (Math.abs(cx(hb) - docW / 2) < 0.1 * docW && display?.align !== "left") hero = "centred";
573
+ else hero = "type-only";
574
+ }
575
+ if (hero === "type-only" && colXs.length >= 3) hero = "editorial";
576
+
577
+ // How the object is framed.
578
+ let frame = "none";
579
+ if (hero === "full-bleed") frame = "bleed";
580
+ else if (hero === "gallery") {
581
+ // A gallery's frame is its container's: the smallest element that holds three of its pictures.
582
+ let box = galleryItems[0].el;
583
+ while (box && box !== document.body && galleryItems.filter((m) => box.contains(m.el)).length < 3) box = box.parentElement;
584
+ const b = box && boxOf(box);
585
+ if (!box || box === document.body || b.w >= 0.95 * docW) frame = b && b.w >= 0.95 * docW ? "bleed" : "flat";
586
+ else {
587
+ const cs = getComputedStyle(box);
588
+ const own = rgba(cs.backgroundColor);
589
+ frame = shadowOf(cs) ? "shadow-card" : borderSides(box, cs) >= 3 || (own && own[3] > 0.5 && dist(over(own, paintedBg(box.parentElement)), paintedBg(box.parentElement)) > 6) ? "border-card" : "flat";
590
+ }
591
+ } else if (object) {
592
+ if (object.b.w >= 0.95 * docW) frame = "bleed";
593
+ else {
594
+ // The frame may be the object itself, its wrapper (up to 1.5x its area) or its first child.
595
+ let f = null;
596
+ for (let e = object.el, k = 0; e && e !== document.body && k < 4; e = e.parentElement, k++) {
597
+ const r = boxOf(e);
598
+ if (area(r) > 1.6 * area(object.b)) break;
599
+ const cs = getComputedStyle(e);
600
+ if (shadowOf(cs)) {
601
+ f = "shadow-card";
602
+ break;
603
+ }
604
+ if (borderSides(e, cs) >= 3) f = f ?? "border-card";
605
+ }
606
+ if (!f) {
607
+ const kid = object.el.firstElementChild;
608
+ const cs = kid && getComputedStyle(kid);
609
+ if (cs && shadowOf(cs) && area(boxOf(kid)) >= 0.6 * area(object.b)) f = "shadow-card";
610
+ else if (cs && borderSides(kid, cs) >= 3 && area(boxOf(kid)) >= 0.6 * area(object.b)) f = "border-card";
611
+ }
612
+ if (!f && !object.media && object.ground) f = "border-card";
613
+ frame = f ?? "flat";
614
+ }
615
+ }
616
+
617
+ // ---- imagery over the page, by area: pictures, drawings, product UI built in the page
618
+ const imageryArea = { photo: 0, illustration: 0, "product-ui": 0 };
619
+ for (const m of media) {
620
+ const a = area(m.b);
621
+ if (/screenshot|dashboard|app|interface|\bui\b|product|editor|inbox/i.test(`${m.alt} ${m.src}`) && m.kind === "photo") imageryArea["product-ui"] += a;
622
+ else if (m.kind === "canvas" || m.kind === "embed") imageryArea["product-ui"] += a * 0.5;
623
+ else imageryArea[m.kind] = (imageryArea[m.kind] ?? 0) + a;
624
+ }
625
+ // Product UI built in HTML: a framed panel of small text, controls and inner boxes (a mock app window, a board).
626
+ const counted = [];
627
+ for (const { el, b, cs } of els) {
628
+ if (b.w < 280 || b.h < 180 || b.w > 0.92 * docW) continue;
629
+ if (counted.some((c) => c.contains(el))) continue;
630
+ const framedHere = shadowOf(cs) || borderSides(el, cs) >= 3 || (rgba(cs.backgroundColor)?.[3] ?? 0) > 0.5;
631
+ if (!framedHere) continue;
632
+ const inside = texts.filter((t) => el.contains(t.el));
633
+ const small = inside.filter((t) => t.size <= 14).length;
634
+ const inner = el.querySelectorAll("button, input, [role=button], [role=tab], [role=row], li, td, [class*=row i], [class*=chip i], [class*=badge i], [class*=pill i]").length;
635
+ if (small >= 8 && inner >= 4 && !inside.some((t) => t.size >= 34)) {
636
+ imageryArea["product-ui"] += area(b);
637
+ counted.push(el);
638
+ }
639
+ }
640
+ const imgTotal = Object.values(imageryArea).reduce((x, y) => x + y, 0);
641
+
642
+ // ---- density: ink on a coarse grid over the first three screens (text lines, media, framed surfaces)
643
+ const cell = 32;
644
+ const H = Math.min(pageH, vh * 3);
645
+ const cols = Math.ceil(docW / cell), rows = Math.ceil(H / cell);
646
+ const grid = new Uint8Array(cols * rows);
647
+ const mark = (b) => {
648
+ const x0 = Math.max(0, b.x), y0 = Math.max(0, b.y), x1 = Math.min(docW, b.x + b.w), y1 = Math.min(H, b.y + b.h);
649
+ if (x1 - x0 < 1 || y1 - y0 < 1) return;
650
+ for (let r = Math.floor(y0 / cell); r < Math.ceil(y1 / cell); r++) for (let c = Math.floor(x0 / cell); c < Math.ceil(x1 / cell); c++) grid[r * cols + c] = 1;
651
+ };
652
+ for (const t of texts) for (const r of t.rects) mark(r);
653
+ for (const m of media) if (!(m.b.w >= 0.9 * docW && m.b.h >= 0.6 * vh)) mark(m.b);
654
+ for (const o of objects) if (!o.media) mark(o.b);
655
+ let inked = 0;
656
+ for (const v of grid) inked += v;
657
+ const textChars = texts.filter((t) => t.rects.some((r) => r.y < H)).reduce((x, t) => x + t.text.trim().length, 0);
658
+
659
+ // ---- colour in large areas: grounds and surfaces by area, for the accent and how colourful the page is
660
+ const fills = [];
661
+ for (const { el, b, cs } of els) {
662
+ const own = rgba(cs.backgroundColor);
663
+ if (!own || own[3] < 0.6 || b.w * b.h < 2000) continue;
664
+ const a = Math.min(area(b), docW * pageH);
665
+ fills.push({ hex: hex(own), a: Math.round(a) });
666
+ }
667
+ for (const b of bands) fills.push({ hex: b.bg, a: b.h * docW, band: true });
668
+ const textColours = new Map();
669
+ for (const t of texts) {
670
+ const h = hex(rgba(t.cs.color));
671
+ textColours.set(h, (textColours.get(h) ?? 0) + t.text.length * t.size * t.size * 0.6);
672
+ }
673
+
674
+ return {
675
+ width: docW,
676
+ pageH,
677
+ vh,
678
+ rootBg: hex(rootBg),
679
+ bands,
680
+ firstScreenPhoto: Boolean(groundPhoto),
681
+ texture,
682
+ textureWhy: textureWhy.slice(0, 4),
683
+ display,
684
+ body,
685
+ header,
686
+ cta: primary ? { style: primary.s.style, shape: primary.s.shape, fill: primary.s.fill, text: primary.s.text, radius: primary.s.radius } : null,
687
+ secondary,
688
+ buttons,
689
+ hero,
690
+ heroDebug: { object: object ? { kind: object.kind, b: object.b, tag: object.el.tagName.toLowerCase(), cls: String(object.el.className?.baseVal ?? object.el.className ?? "").slice(0, 60) } : null, head: hb, cols: colXs.length, gallery: galleryItems.length },
691
+ frame,
692
+ imagery: { area: imageryArea, share: +(imgTotal / (docW * pageH)).toFixed(3) },
693
+ ink: +(inked / (cols * rows)).toFixed(3),
694
+ chars: textChars,
695
+ fills,
696
+ textColours: [...textColours.entries()].map(([h, a]) => ({ hex: h, a: Math.round(a) })),
697
+ };
698
+ };