@palate/cli 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +151 -2
- package/bin/palate.mjs +894 -0
- package/kb/anatomy/data-table.md +24 -0
- package/kb/anatomy/empty-state.md +16 -0
- package/kb/anatomy/filter-toolbar.md +19 -0
- package/kb/anatomy/meter.md +16 -0
- package/kb/anatomy/product-window.md +18 -0
- package/kb/anatomy/settings-page.md +18 -0
- package/kb/anatomy/status-indicator.md +17 -0
- package/kb/anatomy/toast-undo.md +16 -0
- package/kb/bench/briefs.json +618 -0
- package/kb/craft/SOURCES.md +48 -0
- package/kb/craft/creativity.md +55 -0
- package/kb/craft/details.md +75 -0
- package/kb/craft/landing-demos.md +46 -0
- package/kb/craft/mistakes.md +73 -0
- package/kb/craft/motion.md +53 -0
- package/kb/craft/principles.md +68 -0
- package/kb/index/discovery.json +1 -0
- package/kb/inspiration/index.json +79 -0
- package/kb/moves/animated-comparison-table.md +58 -0
- package/kb/moves/before-after-slider.md +58 -0
- package/kb/moves/bento-live-tiles.md +57 -0
- package/kb/moves/calm-motion-system.md +63 -0
- package/kb/moves/canvas-grain.md +58 -0
- package/kb/moves/changelog-as-magazine.md +56 -0
- package/kb/moves/code-drawn-diagram.md +56 -0
- package/kb/moves/colophon.md +54 -0
- package/kb/moves/command-palette-site-nav.md +58 -0
- package/kb/moves/confetti-free-celebration.md +58 -0
- package/kb/moves/console-easter-egg.md +57 -0
- package/kb/moves/copy-confirmation.md +57 -0
- package/kb/moves/cursor-reactive-light.md +57 -0
- package/kb/moves/dark-band-contrast-section.md +55 -0
- package/kb/moves/designed-dark-mode.md +58 -0
- package/kb/moves/duotone-photography.md +55 -0
- package/kb/moves/editorial-drop-cap.md +58 -0
- package/kb/moves/editorial-grid-pull-quotes.md +55 -0
- package/kb/moves/engraving-colour-lens.md +64 -0
- package/kb/moves/explorable-control.md +57 -0
- package/kb/moves/feature-films-on-painted-stages.md +58 -0
- package/kb/moves/first-win-onboarding.md +59 -0
- package/kb/moves/footer-live-status.md +56 -0
- package/kb/moves/footer-rewards-the-end.md +58 -0
- package/kb/moves/generative-brand-pattern.md +55 -0
- package/kb/moves/gentle-error-nudge.md +59 -0
- package/kb/moves/halftone-dot-imagery.md +55 -0
- package/kb/moves/hand-drawn-annotations.md +55 -0
- package/kb/moves/hero-paints-itself-in.md +65 -0
- package/kb/moves/honest-progress-narration.md +58 -0
- package/kb/moves/honest-testimonial-wall.md +57 -0
- package/kb/moves/inline-sparklines-in-copy.md +57 -0
- package/kb/moves/inspect-our-taste.md +58 -0
- package/kb/moves/interactive-pricing-calculator.md +59 -0
- package/kb/moves/isometric-illustration-system.md +56 -0
- package/kb/moves/kinetic-variable-type.md +57 -0
- package/kb/moves/konami-secret.md +59 -0
- package/kb/moves/layered-paper-depth.md +56 -0
- package/kb/moves/lightweight-3d-object-hero.md +59 -0
- package/kb/moves/line-engraving-from-image.md +63 -0
- package/kb/moves/link-preview-peek.md +57 -0
- package/kb/moves/live-data-ticker.md +61 -0
- package/kb/moves/made-with-proof.md +51 -0
- package/kb/moves/magnetic-buttons.md +55 -0
- package/kb/moves/marquee-done-right.md +58 -0
- package/kb/moves/moves.yaml +450 -0
- package/kb/moves/museum-painting-backdrop.md +59 -0
- package/kb/moves/one-colour-brand-world.md +56 -0
- package/kb/moves/playful-404.md +58 -0
- package/kb/moves/pointer-highlight-word.md +56 -0
- package/kb/moves/product-in-context.md +56 -0
- package/kb/moves/real-world-data.md +58 -0
- package/kb/moves/referral-reward-reveal.md +59 -0
- package/kb/moves/riso-print-texture.md +57 -0
- package/kb/moves/screenshot-detail-crops.md +56 -0
- package/kb/moves/scroll-progress-chapters.md +57 -0
- package/kb/moves/scroll-scrubbed-product-film.md +62 -0
- package/kb/moves/self-playing-product-demo.md +61 -0
- package/kb/moves/shape-continuity-morph.md +58 -0
- package/kb/moves/sliding-nav-indicator.md +58 -0
- package/kb/moves/sticky-scroll-story.md +56 -0
- package/kb/moves/story-led-long-scroll.md +56 -0
- package/kb/moves/tactile-button.md +63 -0
- package/kb/moves/technical-drawing-lines.md +57 -0
- package/kb/moves/time-of-day-theming.md +56 -0
- package/kb/moves/tiny-game-easter-egg.md +60 -0
- package/kb/moves/type-decode-reveal.md +57 -0
- package/kb/moves/typographic-numeral-hero.md +58 -0
- package/kb/moves/view-transitions-between-pages.md +57 -0
- package/kb/moves/waitlist-position-live.md +60 -0
- package/kb/patterns/app-team-members.md +27 -0
- package/kb/patterns/chat-agent-approvals.md +31 -0
- package/kb/patterns/commerce-product-page.md +34 -0
- package/kb/patterns/dashboard-entity-table.md +37 -0
- package/kb/patterns/dashboard-home-today.md +24 -0
- package/kb/patterns/docs-api-reference.md +31 -0
- package/kb/patterns/marketing-product-led-landing.md +30 -0
- package/kb/patterns/mobile-daily-checklist.md +26 -0
- package/kb/references/index.json +1 -0
- package/kb/references/thumbs/004c5e9072.jpg +0 -0
- package/kb/references/thumbs/008915eb21.jpg +0 -0
- package/kb/references/thumbs/0098cf66c2.jpg +0 -0
- package/kb/references/thumbs/012e61b31f.jpg +0 -0
- package/kb/references/thumbs/014d4e46fc.jpg +0 -0
- package/kb/references/thumbs/01e54f394a.jpg +0 -0
- package/kb/references/thumbs/01e99a579c.jpg +0 -0
- package/kb/references/thumbs/01fd014575.jpg +0 -0
- package/kb/references/thumbs/022778ca72.jpg +0 -0
- package/kb/references/thumbs/02717bf1e1.jpg +0 -0
- package/kb/references/thumbs/02a5cfdbe9.jpg +0 -0
- package/kb/references/thumbs/02c9823f8d.jpg +0 -0
- package/kb/references/thumbs/02f3974613.jpg +0 -0
- package/kb/references/thumbs/032427f1ce.jpg +0 -0
- package/kb/references/thumbs/03ba677d07.jpg +0 -0
- package/kb/references/thumbs/04f2476cfe.jpg +0 -0
- package/kb/references/thumbs/0563e7c52e.jpg +0 -0
- package/kb/references/thumbs/05fa6b8eef.jpg +0 -0
- package/kb/references/thumbs/065bce1517.jpg +0 -0
- package/kb/references/thumbs/06c017f113.jpg +0 -0
- package/kb/references/thumbs/0770e2d8d3.jpg +0 -0
- package/kb/references/thumbs/078a26c4cb.jpg +0 -0
- package/kb/references/thumbs/08679b6e84.jpg +0 -0
- package/kb/references/thumbs/088c45a34c.jpg +0 -0
- package/kb/references/thumbs/089e9fd4e4.jpg +0 -0
- package/kb/references/thumbs/08f773231e.jpg +0 -0
- package/kb/references/thumbs/093ca3e2e3.jpg +0 -0
- package/kb/references/thumbs/0963320f74.jpg +0 -0
- package/kb/references/thumbs/09fc1ded85.jpg +0 -0
- package/kb/references/thumbs/0a368f3963.jpg +0 -0
- package/kb/references/thumbs/0a9e0e5201.jpg +0 -0
- package/kb/references/thumbs/0aace67ee7.jpg +0 -0
- package/kb/references/thumbs/0b61ecf793.jpg +0 -0
- package/kb/references/thumbs/0bde18ae09.jpg +0 -0
- package/kb/references/thumbs/0bf7ee8143.jpg +0 -0
- package/kb/references/thumbs/0ca20a13e0.jpg +0 -0
- package/kb/references/thumbs/0cdc0198c4.jpg +0 -0
- package/kb/references/thumbs/0cf9790b28.jpg +0 -0
- package/kb/references/thumbs/0d0202904b.jpg +0 -0
- package/kb/references/thumbs/0d053aba18.jpg +0 -0
- package/kb/references/thumbs/0d0c2c13d2.jpg +0 -0
- package/kb/references/thumbs/0d30be99b0.jpg +0 -0
- package/kb/references/thumbs/0d503da1b7.jpg +0 -0
- package/kb/references/thumbs/0ddad7b740.jpg +0 -0
- package/kb/references/thumbs/0e0a148101.jpg +0 -0
- package/kb/references/thumbs/0e401b6b75.jpg +0 -0
- package/kb/references/thumbs/0e8f32ba0f.jpg +0 -0
- package/kb/references/thumbs/0ef1966a7d.jpg +0 -0
- package/kb/references/thumbs/0efd416d11.jpg +0 -0
- package/kb/references/thumbs/0f3af263ae.jpg +0 -0
- package/kb/references/thumbs/0f9644c3a5.jpg +0 -0
- package/kb/references/thumbs/1020552737.jpg +0 -0
- package/kb/references/thumbs/1037626587.jpg +0 -0
- package/kb/references/thumbs/10512b7e94.jpg +0 -0
- package/kb/references/thumbs/106dc4a7b5.jpg +0 -0
- package/kb/references/thumbs/108943f6f7.jpg +0 -0
- package/kb/references/thumbs/10a5551d51.jpg +0 -0
- package/kb/references/thumbs/10dd01076c.jpg +0 -0
- package/kb/references/thumbs/11b06e39da.jpg +0 -0
- package/kb/references/thumbs/11baa1ec83.jpg +0 -0
- package/kb/references/thumbs/11bbe12167.jpg +0 -0
- package/kb/references/thumbs/11ca37feb8.jpg +0 -0
- package/kb/references/thumbs/11f14d3f12.jpg +0 -0
- package/kb/references/thumbs/124530ceb5.jpg +0 -0
- package/kb/references/thumbs/1276402336.jpg +0 -0
- package/kb/references/thumbs/1280e5c9d6.jpg +0 -0
- package/kb/references/thumbs/12cac0d172.jpg +0 -0
- package/kb/references/thumbs/138be6623a.jpg +0 -0
- package/kb/references/thumbs/13a0c544d1.jpg +0 -0
- package/kb/references/thumbs/13a32cb94c.jpg +0 -0
- package/kb/references/thumbs/144035d641.jpg +0 -0
- package/kb/references/thumbs/1457e41924.jpg +0 -0
- package/kb/references/thumbs/14972e3a86.jpg +0 -0
- package/kb/references/thumbs/15a47f2e4c.jpg +0 -0
- package/kb/references/thumbs/15aa15d22e.jpg +0 -0
- package/kb/references/thumbs/160dcd24b7.jpg +0 -0
- package/kb/references/thumbs/1610978529.jpg +0 -0
- package/kb/references/thumbs/16db30ba37.jpg +0 -0
- package/kb/references/thumbs/16f19ae4f3.jpg +0 -0
- package/kb/references/thumbs/16f758b03f.jpg +0 -0
- package/kb/references/thumbs/1748e5b751.jpg +0 -0
- package/kb/references/thumbs/175d0b0e69.jpg +0 -0
- package/kb/references/thumbs/178f571a36.jpg +0 -0
- package/kb/references/thumbs/17c43dc025.jpg +0 -0
- package/kb/references/thumbs/17c7f05b50.jpg +0 -0
- package/kb/references/thumbs/17f97e61dd.jpg +0 -0
- package/kb/references/thumbs/1804e17365.jpg +0 -0
- package/kb/references/thumbs/195c162ed1.jpg +0 -0
- package/kb/references/thumbs/19e3699c29.jpg +0 -0
- package/kb/references/thumbs/1a48e0a4d5.jpg +0 -0
- package/kb/references/thumbs/1a6cda265e.jpg +0 -0
- package/kb/references/thumbs/1a7e012091.jpg +0 -0
- package/kb/references/thumbs/1a9173a172.jpg +0 -0
- package/kb/references/thumbs/1b34a6b4d2.jpg +0 -0
- package/kb/references/thumbs/1b5284f3b2.jpg +0 -0
- package/kb/references/thumbs/1b93fbd6d3.jpg +0 -0
- package/kb/references/thumbs/1c6728fef6.jpg +0 -0
- package/kb/references/thumbs/1c6f101618.jpg +0 -0
- package/kb/references/thumbs/1cf7011a94.jpg +0 -0
- package/kb/references/thumbs/1d1769e539.jpg +0 -0
- package/kb/references/thumbs/1d1fd23199.jpg +0 -0
- package/kb/references/thumbs/1d7b6602ac.jpg +0 -0
- package/kb/references/thumbs/1dbbc61b9e.jpg +0 -0
- package/kb/references/thumbs/1dbdd6d21d.jpg +0 -0
- package/kb/references/thumbs/1dd873744b.jpg +0 -0
- package/kb/references/thumbs/1df4dd7cf9.jpg +0 -0
- package/kb/references/thumbs/1ece8c35b8.jpg +0 -0
- package/kb/references/thumbs/1f0e5b9aa4.jpg +0 -0
- package/kb/references/thumbs/1f1419651b.jpg +0 -0
- package/kb/references/thumbs/1f2a6da92d.jpg +0 -0
- package/kb/references/thumbs/1f651f33c0.jpg +0 -0
- package/kb/references/thumbs/1f8b697d18.jpg +0 -0
- package/kb/references/thumbs/1fee3824cd.jpg +0 -0
- package/kb/references/thumbs/1ff7757853.jpg +0 -0
- package/kb/references/thumbs/2043182f01.jpg +0 -0
- package/kb/references/thumbs/2059dabcd5.jpg +0 -0
- package/kb/references/thumbs/209d9dbb95.jpg +0 -0
- package/kb/references/thumbs/20d8923554.jpg +0 -0
- package/kb/references/thumbs/210dd3b671.jpg +0 -0
- package/kb/references/thumbs/2120719116.jpg +0 -0
- package/kb/references/thumbs/21a7384429.jpg +0 -0
- package/kb/references/thumbs/225f187391.jpg +0 -0
- package/kb/references/thumbs/230caf7dd2.jpg +0 -0
- package/kb/references/thumbs/235afad355.jpg +0 -0
- package/kb/references/thumbs/2378066687.jpg +0 -0
- package/kb/references/thumbs/241faf68a1.jpg +0 -0
- package/kb/references/thumbs/24d9f1a9b9.jpg +0 -0
- package/kb/references/thumbs/2505c8b9a0.jpg +0 -0
- package/kb/references/thumbs/25593638ca.jpg +0 -0
- package/kb/references/thumbs/25dd454f18.jpg +0 -0
- package/kb/references/thumbs/2602e123e2.jpg +0 -0
- package/kb/references/thumbs/26095c0b11.jpg +0 -0
- package/kb/references/thumbs/26260d6238.jpg +0 -0
- package/kb/references/thumbs/26bba21836.jpg +0 -0
- package/kb/references/thumbs/26bde3520b.jpg +0 -0
- package/kb/references/thumbs/272e22067c.jpg +0 -0
- package/kb/references/thumbs/27421b3226.jpg +0 -0
- package/kb/references/thumbs/2769ebca41.jpg +0 -0
- package/kb/references/thumbs/27e2f6e8b0.jpg +0 -0
- package/kb/references/thumbs/28432ba373.jpg +0 -0
- package/kb/references/thumbs/2846626f19.jpg +0 -0
- package/kb/references/thumbs/28750e821e.jpg +0 -0
- package/kb/references/thumbs/289481230f.jpg +0 -0
- package/kb/references/thumbs/2897967408.jpg +0 -0
- package/kb/references/thumbs/28c0a5fa17.jpg +0 -0
- package/kb/references/thumbs/28c181fba5.jpg +0 -0
- package/kb/references/thumbs/29806f539f.jpg +0 -0
- package/kb/references/thumbs/2997f56ee7.jpg +0 -0
- package/kb/references/thumbs/29b34a10fb.jpg +0 -0
- package/kb/references/thumbs/29bd78cdb4.jpg +0 -0
- package/kb/references/thumbs/29c8c6c22a.jpg +0 -0
- package/kb/references/thumbs/2ac23f7fae.jpg +0 -0
- package/kb/references/thumbs/2b76e13f79.jpg +0 -0
- package/kb/references/thumbs/2b84226479.jpg +0 -0
- package/kb/references/thumbs/2bf2dbf737.jpg +0 -0
- package/kb/references/thumbs/2bf89abbf6.jpg +0 -0
- package/kb/references/thumbs/2c562cd534.jpg +0 -0
- package/kb/references/thumbs/2cfe9d48c4.jpg +0 -0
- package/kb/references/thumbs/2d49f19b27.jpg +0 -0
- package/kb/references/thumbs/2dc8670da7.jpg +0 -0
- package/kb/references/thumbs/2de947c469.jpg +0 -0
- package/kb/references/thumbs/2e075ca79f.jpg +0 -0
- package/kb/references/thumbs/2eb0820e6b.jpg +0 -0
- package/kb/references/thumbs/2ec56a9dc0.jpg +0 -0
- package/kb/references/thumbs/30bb4ad607.jpg +0 -0
- package/kb/references/thumbs/30d19b8444.jpg +0 -0
- package/kb/references/thumbs/3173c71d73.jpg +0 -0
- package/kb/references/thumbs/31e59e4518.jpg +0 -0
- package/kb/references/thumbs/322b8960e8.jpg +0 -0
- package/kb/references/thumbs/325c9be6f4.jpg +0 -0
- package/kb/references/thumbs/3273338982.jpg +0 -0
- package/kb/references/thumbs/32f8387f38.jpg +0 -0
- package/kb/references/thumbs/332f6b74c3.jpg +0 -0
- package/kb/references/thumbs/334b146b6a.jpg +0 -0
- package/kb/references/thumbs/339abd60e4.jpg +0 -0
- package/kb/references/thumbs/33e88ec295.jpg +0 -0
- package/kb/references/thumbs/340931b5d4.jpg +0 -0
- package/kb/references/thumbs/34165a93bd.jpg +0 -0
- package/kb/references/thumbs/34d0575dd7.jpg +0 -0
- package/kb/references/thumbs/3549e75f0a.jpg +0 -0
- package/kb/references/thumbs/35827f1561.jpg +0 -0
- package/kb/references/thumbs/37c50280ec.jpg +0 -0
- package/kb/references/thumbs/37e66ecf11.jpg +0 -0
- package/kb/references/thumbs/3841a04fdc.jpg +0 -0
- package/kb/references/thumbs/38490c088f.jpg +0 -0
- package/kb/references/thumbs/3850319e9f.jpg +0 -0
- package/kb/references/thumbs/3856a64166.jpg +0 -0
- package/kb/references/thumbs/3881f211c2.jpg +0 -0
- package/kb/references/thumbs/38c7dde2f3.jpg +0 -0
- package/kb/references/thumbs/38ce9e486c.jpg +0 -0
- package/kb/references/thumbs/390ea8e01b.jpg +0 -0
- package/kb/references/thumbs/391b7fc27c.jpg +0 -0
- package/kb/references/thumbs/395f7214dc.jpg +0 -0
- package/kb/references/thumbs/39e81a5db2.jpg +0 -0
- package/kb/references/thumbs/3a67c8d655.jpg +0 -0
- package/kb/references/thumbs/3a89c25e3b.jpg +0 -0
- package/kb/references/thumbs/3aa0837542.jpg +0 -0
- package/kb/references/thumbs/3aae18aa8a.jpg +0 -0
- package/kb/references/thumbs/3bdbe767db.jpg +0 -0
- package/kb/references/thumbs/3c0616fc7f.jpg +0 -0
- package/kb/references/thumbs/3c18e9db1d.jpg +0 -0
- package/kb/references/thumbs/3c5a14076c.jpg +0 -0
- package/kb/references/thumbs/3ca9ec15c6.jpg +0 -0
- package/kb/references/thumbs/3d7756fd35.jpg +0 -0
- package/kb/references/thumbs/3dd45bd33d.jpg +0 -0
- package/kb/references/thumbs/3de72d5414.jpg +0 -0
- package/kb/references/thumbs/3dede597af.jpg +0 -0
- package/kb/references/thumbs/3ea948619e.jpg +0 -0
- package/kb/references/thumbs/402c12054c.jpg +0 -0
- package/kb/references/thumbs/403ab4af90.jpg +0 -0
- package/kb/references/thumbs/40773a8c63.jpg +0 -0
- package/kb/references/thumbs/407d9583db.jpg +0 -0
- package/kb/references/thumbs/415dc1d84c.jpg +0 -0
- package/kb/references/thumbs/420b676a4f.jpg +0 -0
- package/kb/references/thumbs/42a1ee85eb.jpg +0 -0
- package/kb/references/thumbs/43059221aa.jpg +0 -0
- package/kb/references/thumbs/432fa0d22c.jpg +0 -0
- package/kb/references/thumbs/43826f20e3.jpg +0 -0
- package/kb/references/thumbs/43ac55c98a.jpg +0 -0
- package/kb/references/thumbs/43d098f3c3.jpg +0 -0
- package/kb/references/thumbs/4449d80c2c.jpg +0 -0
- package/kb/references/thumbs/44625727dc.jpg +0 -0
- package/kb/references/thumbs/4482bb87a1.jpg +0 -0
- package/kb/references/thumbs/44b078acdc.jpg +0 -0
- package/kb/references/thumbs/44d0305850.jpg +0 -0
- package/kb/references/thumbs/456bb6b59e.jpg +0 -0
- package/kb/references/thumbs/45df73ce48.jpg +0 -0
- package/kb/references/thumbs/45edb45d87.jpg +0 -0
- package/kb/references/thumbs/4671d57cd5.jpg +0 -0
- package/kb/references/thumbs/46cc108518.jpg +0 -0
- package/kb/references/thumbs/470022e614.jpg +0 -0
- package/kb/references/thumbs/4719a669ce.jpg +0 -0
- package/kb/references/thumbs/47404f5ad4.jpg +0 -0
- package/kb/references/thumbs/479d3eb977.jpg +0 -0
- package/kb/references/thumbs/479ed92ceb.jpg +0 -0
- package/kb/references/thumbs/47baed50c7.jpg +0 -0
- package/kb/references/thumbs/47fdcfd7b0.jpg +0 -0
- package/kb/references/thumbs/48fd5e94c5.jpg +0 -0
- package/kb/references/thumbs/493807917b.jpg +0 -0
- package/kb/references/thumbs/49a1c67293.jpg +0 -0
- package/kb/references/thumbs/49e2d7fafe.jpg +0 -0
- package/kb/references/thumbs/49f540fcb6.jpg +0 -0
- package/kb/references/thumbs/4a67ec4028.jpg +0 -0
- package/kb/references/thumbs/4a93275b04.jpg +0 -0
- package/kb/references/thumbs/4aae6f52da.jpg +0 -0
- package/kb/references/thumbs/4b1bae66bd.jpg +0 -0
- package/kb/references/thumbs/4b75da15a9.jpg +0 -0
- package/kb/references/thumbs/4b77789b88.jpg +0 -0
- package/kb/references/thumbs/4bc2f3f3a4.jpg +0 -0
- package/kb/references/thumbs/4c48f27b88.jpg +0 -0
- package/kb/references/thumbs/4c52bd8bfb.jpg +0 -0
- package/kb/references/thumbs/4c9b4acc60.jpg +0 -0
- package/kb/references/thumbs/4cbf0752d4.jpg +0 -0
- package/kb/references/thumbs/4cd2672517.jpg +0 -0
- package/kb/references/thumbs/4dd22a8181.jpg +0 -0
- package/kb/references/thumbs/4ee3447314.jpg +0 -0
- package/kb/references/thumbs/4ef29c8144.jpg +0 -0
- package/kb/references/thumbs/4f82fadfd6.jpg +0 -0
- package/kb/references/thumbs/4fc9b643d8.jpg +0 -0
- package/kb/references/thumbs/50549524b0.jpg +0 -0
- package/kb/references/thumbs/509a615883.jpg +0 -0
- package/kb/references/thumbs/50c03ef855.jpg +0 -0
- package/kb/references/thumbs/50cf9acad6.jpg +0 -0
- package/kb/references/thumbs/51131b025c.jpg +0 -0
- package/kb/references/thumbs/51da1124f0.jpg +0 -0
- package/kb/references/thumbs/524d5e7288.jpg +0 -0
- package/kb/references/thumbs/5251247c81.jpg +0 -0
- package/kb/references/thumbs/526b91b7ec.jpg +0 -0
- package/kb/references/thumbs/52f02f6c2e.jpg +0 -0
- package/kb/references/thumbs/530ab530dc.jpg +0 -0
- package/kb/references/thumbs/5335ee4404.jpg +0 -0
- package/kb/references/thumbs/5385b90939.jpg +0 -0
- package/kb/references/thumbs/53c54654cc.jpg +0 -0
- package/kb/references/thumbs/5420794c6c.jpg +0 -0
- package/kb/references/thumbs/542a9dce8b.jpg +0 -0
- package/kb/references/thumbs/5571530a5f.jpg +0 -0
- package/kb/references/thumbs/56cc68d804.jpg +0 -0
- package/kb/references/thumbs/577b7f7c44.jpg +0 -0
- package/kb/references/thumbs/57adf8f1bb.jpg +0 -0
- package/kb/references/thumbs/57c5f5e3a6.jpg +0 -0
- package/kb/references/thumbs/57ffe4e839.jpg +0 -0
- package/kb/references/thumbs/5817dfc7d6.jpg +0 -0
- package/kb/references/thumbs/581a182a7a.jpg +0 -0
- package/kb/references/thumbs/58807679c8.jpg +0 -0
- package/kb/references/thumbs/589a1d9111.jpg +0 -0
- package/kb/references/thumbs/59167391ab.jpg +0 -0
- package/kb/references/thumbs/5a70420166.jpg +0 -0
- package/kb/references/thumbs/5b10df1b8d.jpg +0 -0
- package/kb/references/thumbs/5b7a712fdb.jpg +0 -0
- package/kb/references/thumbs/5bc46b92ad.jpg +0 -0
- package/kb/references/thumbs/5c0546a120.jpg +0 -0
- package/kb/references/thumbs/5c2b6125a8.jpg +0 -0
- package/kb/references/thumbs/5c536b9e42.jpg +0 -0
- package/kb/references/thumbs/5c8e441d30.jpg +0 -0
- package/kb/references/thumbs/5cb6f1baa5.jpg +0 -0
- package/kb/references/thumbs/5ce6c1f21e.jpg +0 -0
- package/kb/references/thumbs/5cef052c0a.jpg +0 -0
- package/kb/references/thumbs/5d08438209.jpg +0 -0
- package/kb/references/thumbs/5d0f9af9b0.jpg +0 -0
- package/kb/references/thumbs/5d300ed332.jpg +0 -0
- package/kb/references/thumbs/5d708a4794.jpg +0 -0
- package/kb/references/thumbs/5de8826a98.jpg +0 -0
- package/kb/references/thumbs/5df7bff22c.jpg +0 -0
- package/kb/references/thumbs/5e087d0f00.jpg +0 -0
- package/kb/references/thumbs/5e44e70ca0.jpg +0 -0
- package/kb/references/thumbs/5eff5d80ce.jpg +0 -0
- package/kb/references/thumbs/5f015c96b1.jpg +0 -0
- package/kb/references/thumbs/5f3289b7c4.jpg +0 -0
- package/kb/references/thumbs/5f830c40eb.jpg +0 -0
- package/kb/references/thumbs/60c4c3527b.jpg +0 -0
- package/kb/references/thumbs/60e9e594dd.jpg +0 -0
- package/kb/references/thumbs/615421d7be.jpg +0 -0
- package/kb/references/thumbs/6176e4004f.jpg +0 -0
- package/kb/references/thumbs/61f0fe5e06.jpg +0 -0
- package/kb/references/thumbs/6213785db4.jpg +0 -0
- package/kb/references/thumbs/62a670ae09.jpg +0 -0
- package/kb/references/thumbs/63cc12981b.jpg +0 -0
- package/kb/references/thumbs/641f15cc71.jpg +0 -0
- package/kb/references/thumbs/642ab2081d.jpg +0 -0
- package/kb/references/thumbs/644a59bf6e.jpg +0 -0
- package/kb/references/thumbs/644da8a8e3.jpg +0 -0
- package/kb/references/thumbs/6458986897.jpg +0 -0
- package/kb/references/thumbs/64cfbd7b93.jpg +0 -0
- package/kb/references/thumbs/661a57686a.jpg +0 -0
- package/kb/references/thumbs/66355a813a.jpg +0 -0
- package/kb/references/thumbs/664396dd44.jpg +0 -0
- package/kb/references/thumbs/66d832d65f.jpg +0 -0
- package/kb/references/thumbs/66de9e9833.jpg +0 -0
- package/kb/references/thumbs/6750964fd9.jpg +0 -0
- package/kb/references/thumbs/67c7164832.jpg +0 -0
- package/kb/references/thumbs/681600b6cd.jpg +0 -0
- package/kb/references/thumbs/682e75afe4.jpg +0 -0
- package/kb/references/thumbs/69274bc952.jpg +0 -0
- package/kb/references/thumbs/696ec08c52.jpg +0 -0
- package/kb/references/thumbs/69760111cc.jpg +0 -0
- package/kb/references/thumbs/697e32664f.jpg +0 -0
- package/kb/references/thumbs/69df92544b.jpg +0 -0
- package/kb/references/thumbs/69e48c5229.jpg +0 -0
- package/kb/references/thumbs/6a5fb75de1.jpg +0 -0
- package/kb/references/thumbs/6a7389e472.jpg +0 -0
- package/kb/references/thumbs/6a9b041e02.jpg +0 -0
- package/kb/references/thumbs/6ab2fa93ee.jpg +0 -0
- package/kb/references/thumbs/6ae3400319.jpg +0 -0
- package/kb/references/thumbs/6b21344bf3.jpg +0 -0
- package/kb/references/thumbs/6bd1b67a8a.jpg +0 -0
- package/kb/references/thumbs/6c99156c4f.jpg +0 -0
- package/kb/references/thumbs/6cc9b65384.jpg +0 -0
- package/kb/references/thumbs/6d15830a73.jpg +0 -0
- package/kb/references/thumbs/6d4c33d180.jpg +0 -0
- package/kb/references/thumbs/6e36815799.jpg +0 -0
- package/kb/references/thumbs/6eddb9cbfc.jpg +0 -0
- package/kb/references/thumbs/6f97968a7c.jpg +0 -0
- package/kb/references/thumbs/6fa0716a7d.jpg +0 -0
- package/kb/references/thumbs/6facd57184.jpg +0 -0
- package/kb/references/thumbs/6fd57b785a.jpg +0 -0
- package/kb/references/thumbs/700b3cb185.jpg +0 -0
- package/kb/references/thumbs/71197443fa.jpg +0 -0
- package/kb/references/thumbs/72082bc9ee.jpg +0 -0
- package/kb/references/thumbs/72453db479.jpg +0 -0
- package/kb/references/thumbs/72cd64d500.jpg +0 -0
- package/kb/references/thumbs/72d1e75283.jpg +0 -0
- package/kb/references/thumbs/72e13f7f5b.jpg +0 -0
- package/kb/references/thumbs/7459f8e644.jpg +0 -0
- package/kb/references/thumbs/7470d55c79.jpg +0 -0
- package/kb/references/thumbs/74c468f02a.jpg +0 -0
- package/kb/references/thumbs/74fed6eb77.jpg +0 -0
- package/kb/references/thumbs/756e05080d.jpg +0 -0
- package/kb/references/thumbs/75df7e5f49.jpg +0 -0
- package/kb/references/thumbs/76226da6ef.jpg +0 -0
- package/kb/references/thumbs/76a34aa056.jpg +0 -0
- package/kb/references/thumbs/76c7076589.jpg +0 -0
- package/kb/references/thumbs/76cccc396c.jpg +0 -0
- package/kb/references/thumbs/774654789f.jpg +0 -0
- package/kb/references/thumbs/7746cc494d.jpg +0 -0
- package/kb/references/thumbs/7766e36aa3.jpg +0 -0
- package/kb/references/thumbs/78049331ef.jpg +0 -0
- package/kb/references/thumbs/78808a0ca5.jpg +0 -0
- package/kb/references/thumbs/7890b0a310.jpg +0 -0
- package/kb/references/thumbs/78911975e6.jpg +0 -0
- package/kb/references/thumbs/78d289d5a0.jpg +0 -0
- package/kb/references/thumbs/794126267e.jpg +0 -0
- package/kb/references/thumbs/7976eb9025.jpg +0 -0
- package/kb/references/thumbs/798519ec7c.jpg +0 -0
- package/kb/references/thumbs/7a6cc5eecc.jpg +0 -0
- package/kb/references/thumbs/7ac8a7cd4a.jpg +0 -0
- package/kb/references/thumbs/7b1341d61d.jpg +0 -0
- package/kb/references/thumbs/7b9c4031e3.jpg +0 -0
- package/kb/references/thumbs/7ba5ad3779.jpg +0 -0
- package/kb/references/thumbs/7be6eb2bd0.jpg +0 -0
- package/kb/references/thumbs/7c30864f5d.jpg +0 -0
- package/kb/references/thumbs/7c379b5e17.jpg +0 -0
- package/kb/references/thumbs/7c4050eb02.jpg +0 -0
- package/kb/references/thumbs/7ca47b3221.jpg +0 -0
- package/kb/references/thumbs/7d43516bd7.jpg +0 -0
- package/kb/references/thumbs/7da9dbb98a.jpg +0 -0
- package/kb/references/thumbs/7ddda8f57c.jpg +0 -0
- package/kb/references/thumbs/7ece6d215c.jpg +0 -0
- package/kb/references/thumbs/7eebf029de.jpg +0 -0
- package/kb/references/thumbs/7f45483c15.jpg +0 -0
- package/kb/references/thumbs/7fde06eaa5.jpg +0 -0
- package/kb/references/thumbs/80407b97e9.jpg +0 -0
- package/kb/references/thumbs/80f0a6cf4b.jpg +0 -0
- package/kb/references/thumbs/8118b451b8.jpg +0 -0
- package/kb/references/thumbs/816baed4a8.jpg +0 -0
- package/kb/references/thumbs/817d2d15d9.jpg +0 -0
- package/kb/references/thumbs/8260cb430d.jpg +0 -0
- package/kb/references/thumbs/827b562899.jpg +0 -0
- package/kb/references/thumbs/8293cf1e92.jpg +0 -0
- package/kb/references/thumbs/8294653169.jpg +0 -0
- package/kb/references/thumbs/83061f871f.jpg +0 -0
- package/kb/references/thumbs/833df778ca.jpg +0 -0
- package/kb/references/thumbs/83d3acaafc.jpg +0 -0
- package/kb/references/thumbs/844c6efeff.jpg +0 -0
- package/kb/references/thumbs/84563d482a.jpg +0 -0
- package/kb/references/thumbs/848082dd94.jpg +0 -0
- package/kb/references/thumbs/8494b1da94.jpg +0 -0
- package/kb/references/thumbs/84b71014be.jpg +0 -0
- package/kb/references/thumbs/84be4a5f3c.jpg +0 -0
- package/kb/references/thumbs/84fd0fd25a.jpg +0 -0
- package/kb/references/thumbs/853e488e22.jpg +0 -0
- package/kb/references/thumbs/858c91585d.jpg +0 -0
- package/kb/references/thumbs/85903e8fe9.jpg +0 -0
- package/kb/references/thumbs/86597d43fd.jpg +0 -0
- package/kb/references/thumbs/866eb99500.jpg +0 -0
- package/kb/references/thumbs/86ac050340.jpg +0 -0
- package/kb/references/thumbs/86afec7b64.jpg +0 -0
- package/kb/references/thumbs/87238127f5.jpg +0 -0
- package/kb/references/thumbs/87321df792.jpg +0 -0
- package/kb/references/thumbs/87460f70cd.jpg +0 -0
- package/kb/references/thumbs/8770dfeaec.jpg +0 -0
- package/kb/references/thumbs/8798451a8c.jpg +0 -0
- package/kb/references/thumbs/87da1f34a3.jpg +0 -0
- package/kb/references/thumbs/882cdf8c05.jpg +0 -0
- package/kb/references/thumbs/8839f4106f.jpg +0 -0
- package/kb/references/thumbs/8844455212.jpg +0 -0
- package/kb/references/thumbs/88abba0497.jpg +0 -0
- package/kb/references/thumbs/88b372435d.jpg +0 -0
- package/kb/references/thumbs/88bd4f35fa.jpg +0 -0
- package/kb/references/thumbs/88c71a075e.jpg +0 -0
- package/kb/references/thumbs/892e5f048e.jpg +0 -0
- package/kb/references/thumbs/893cc8e920.jpg +0 -0
- package/kb/references/thumbs/896c198814.jpg +0 -0
- package/kb/references/thumbs/8a8e22f756.jpg +0 -0
- package/kb/references/thumbs/8a9d8a35cb.jpg +0 -0
- package/kb/references/thumbs/8ab1d67fec.jpg +0 -0
- package/kb/references/thumbs/8ab201fe12.jpg +0 -0
- package/kb/references/thumbs/8ac372c102.jpg +0 -0
- package/kb/references/thumbs/8b15736d62.jpg +0 -0
- package/kb/references/thumbs/8b1d8d6a05.jpg +0 -0
- package/kb/references/thumbs/8bb6050e20.jpg +0 -0
- package/kb/references/thumbs/8c6c9d1577.jpg +0 -0
- package/kb/references/thumbs/8d337851e0.jpg +0 -0
- package/kb/references/thumbs/8d44b33cc5.jpg +0 -0
- package/kb/references/thumbs/8d4536ff3b.jpg +0 -0
- package/kb/references/thumbs/8d9b99454a.jpg +0 -0
- package/kb/references/thumbs/8dda2303ff.jpg +0 -0
- package/kb/references/thumbs/8dec722d62.jpg +0 -0
- package/kb/references/thumbs/8e0ea4ca74.jpg +0 -0
- package/kb/references/thumbs/8ebba84d69.jpg +0 -0
- package/kb/references/thumbs/8ef09140c0.jpg +0 -0
- package/kb/references/thumbs/8f2928a1b0.jpg +0 -0
- package/kb/references/thumbs/8f88f9ddba.jpg +0 -0
- package/kb/references/thumbs/8fa4451009.jpg +0 -0
- package/kb/references/thumbs/90109b0e02.jpg +0 -0
- package/kb/references/thumbs/90e854e5c9.jpg +0 -0
- package/kb/references/thumbs/914e79f893.jpg +0 -0
- package/kb/references/thumbs/9161369197.jpg +0 -0
- package/kb/references/thumbs/9165c87d6f.jpg +0 -0
- package/kb/references/thumbs/9193f6558a.jpg +0 -0
- package/kb/references/thumbs/91ac7df877.jpg +0 -0
- package/kb/references/thumbs/9216bd4931.jpg +0 -0
- package/kb/references/thumbs/922ae8a26a.jpg +0 -0
- package/kb/references/thumbs/92a70e6867.jpg +0 -0
- package/kb/references/thumbs/92c77ece22.jpg +0 -0
- package/kb/references/thumbs/92e5914fbf.jpg +0 -0
- package/kb/references/thumbs/92ee36419a.jpg +0 -0
- package/kb/references/thumbs/94153a60b0.jpg +0 -0
- package/kb/references/thumbs/9449666640.jpg +0 -0
- package/kb/references/thumbs/944be6a646.jpg +0 -0
- package/kb/references/thumbs/945831476e.jpg +0 -0
- package/kb/references/thumbs/94c1af82f4.jpg +0 -0
- package/kb/references/thumbs/9599d6d589.jpg +0 -0
- package/kb/references/thumbs/960710f4cf.jpg +0 -0
- package/kb/references/thumbs/9608f12d64.jpg +0 -0
- package/kb/references/thumbs/962dabfaa0.jpg +0 -0
- package/kb/references/thumbs/965a3a95c6.jpg +0 -0
- package/kb/references/thumbs/9672ed5ae4.jpg +0 -0
- package/kb/references/thumbs/96891ae9c1.jpg +0 -0
- package/kb/references/thumbs/96e1907c99.jpg +0 -0
- package/kb/references/thumbs/96f25b6578.jpg +0 -0
- package/kb/references/thumbs/97211df9ae.jpg +0 -0
- package/kb/references/thumbs/9769d763a5.jpg +0 -0
- package/kb/references/thumbs/9792bd6d05.jpg +0 -0
- package/kb/references/thumbs/97d2837e3e.jpg +0 -0
- package/kb/references/thumbs/97d90d1d85.jpg +0 -0
- package/kb/references/thumbs/97fcd5774a.jpg +0 -0
- package/kb/references/thumbs/980f68564e.jpg +0 -0
- package/kb/references/thumbs/98511fb393.jpg +0 -0
- package/kb/references/thumbs/98f8fa694d.jpg +0 -0
- package/kb/references/thumbs/9a42c6bb97.jpg +0 -0
- package/kb/references/thumbs/9ab3600a06.jpg +0 -0
- package/kb/references/thumbs/9ab48d9130.jpg +0 -0
- package/kb/references/thumbs/9ad519197d.jpg +0 -0
- package/kb/references/thumbs/9b1382c657.jpg +0 -0
- package/kb/references/thumbs/9b6cc1e077.jpg +0 -0
- package/kb/references/thumbs/9beede8480.jpg +0 -0
- package/kb/references/thumbs/9bf8976952.jpg +0 -0
- package/kb/references/thumbs/9cace7b75a.jpg +0 -0
- package/kb/references/thumbs/9cdcc5745e.jpg +0 -0
- package/kb/references/thumbs/9d0b269074.jpg +0 -0
- package/kb/references/thumbs/9d41788b48.jpg +0 -0
- package/kb/references/thumbs/9d475bd6af.jpg +0 -0
- package/kb/references/thumbs/9e6bc543d0.jpg +0 -0
- package/kb/references/thumbs/9ed0e0a206.jpg +0 -0
- package/kb/references/thumbs/9ef538de13.jpg +0 -0
- package/kb/references/thumbs/9efc373ab4.jpg +0 -0
- package/kb/references/thumbs/9f4a939fa5.jpg +0 -0
- package/kb/references/thumbs/9f8d12d7b9.jpg +0 -0
- package/kb/references/thumbs/9fd5e3efa7.jpg +0 -0
- package/kb/references/thumbs/a0a9b9c572.jpg +0 -0
- package/kb/references/thumbs/a29ca9b185.jpg +0 -0
- package/kb/references/thumbs/a2a42884af.jpg +0 -0
- package/kb/references/thumbs/a2f5064e34.jpg +0 -0
- package/kb/references/thumbs/a3112ce672.jpg +0 -0
- package/kb/references/thumbs/a3437736d1.jpg +0 -0
- package/kb/references/thumbs/a372667e76.jpg +0 -0
- package/kb/references/thumbs/a39bae94e9.jpg +0 -0
- package/kb/references/thumbs/a3fc75d94c.jpg +0 -0
- package/kb/references/thumbs/a440487631.jpg +0 -0
- package/kb/references/thumbs/a4993d5fb5.jpg +0 -0
- package/kb/references/thumbs/a500476a86.jpg +0 -0
- package/kb/references/thumbs/a55506bf46.jpg +0 -0
- package/kb/references/thumbs/a59a5f9843.jpg +0 -0
- package/kb/references/thumbs/a5bce0eede.jpg +0 -0
- package/kb/references/thumbs/a5d921e1f0.jpg +0 -0
- package/kb/references/thumbs/a5e19d4637.jpg +0 -0
- package/kb/references/thumbs/a5f92b97d5.jpg +0 -0
- package/kb/references/thumbs/a6562c210a.jpg +0 -0
- package/kb/references/thumbs/a6f61a8d09.jpg +0 -0
- package/kb/references/thumbs/a719fdf663.jpg +0 -0
- package/kb/references/thumbs/a724e5442f.jpg +0 -0
- package/kb/references/thumbs/a852b4319f.jpg +0 -0
- package/kb/references/thumbs/a896c08448.jpg +0 -0
- package/kb/references/thumbs/a8d190a4b8.jpg +0 -0
- package/kb/references/thumbs/a8dcdd57d7.jpg +0 -0
- package/kb/references/thumbs/a951347e18.jpg +0 -0
- package/kb/references/thumbs/a9a1a0bf7d.jpg +0 -0
- package/kb/references/thumbs/a9b72986a8.jpg +0 -0
- package/kb/references/thumbs/aa11555ba8.jpg +0 -0
- package/kb/references/thumbs/aa4aab9093.jpg +0 -0
- package/kb/references/thumbs/aa89b96658.jpg +0 -0
- package/kb/references/thumbs/aaeb3739b6.jpg +0 -0
- package/kb/references/thumbs/ab25a608ec.jpg +0 -0
- package/kb/references/thumbs/ab34b62268.jpg +0 -0
- package/kb/references/thumbs/ab3b0217bb.jpg +0 -0
- package/kb/references/thumbs/ac70c04afb.jpg +0 -0
- package/kb/references/thumbs/ace0879117.jpg +0 -0
- package/kb/references/thumbs/ad0515ae55.jpg +0 -0
- package/kb/references/thumbs/ad66b25b47.jpg +0 -0
- package/kb/references/thumbs/ad68229d2f.jpg +0 -0
- package/kb/references/thumbs/add6480693.jpg +0 -0
- package/kb/references/thumbs/ae5b8c3b8c.jpg +0 -0
- package/kb/references/thumbs/ae81247b47.jpg +0 -0
- package/kb/references/thumbs/af8aa54379.jpg +0 -0
- package/kb/references/thumbs/afa80dedd4.jpg +0 -0
- package/kb/references/thumbs/afe04d730f.jpg +0 -0
- package/kb/references/thumbs/b09a7dc315.jpg +0 -0
- package/kb/references/thumbs/b0c02629f6.jpg +0 -0
- package/kb/references/thumbs/b1cb4f91de.jpg +0 -0
- package/kb/references/thumbs/b1d4c13c92.jpg +0 -0
- package/kb/references/thumbs/b20eef86db.jpg +0 -0
- package/kb/references/thumbs/b3136ccdde.jpg +0 -0
- package/kb/references/thumbs/b3f5e8d7dd.jpg +0 -0
- package/kb/references/thumbs/b44adb81c9.jpg +0 -0
- package/kb/references/thumbs/b457a5894b.jpg +0 -0
- package/kb/references/thumbs/b461281e0f.jpg +0 -0
- package/kb/references/thumbs/b4942644f0.jpg +0 -0
- package/kb/references/thumbs/b49f8eccad.jpg +0 -0
- package/kb/references/thumbs/b56c69be23.jpg +0 -0
- package/kb/references/thumbs/b59786b33c.jpg +0 -0
- package/kb/references/thumbs/b5d368ce5a.jpg +0 -0
- package/kb/references/thumbs/b5eb442406.jpg +0 -0
- package/kb/references/thumbs/b7fdabf4ab.jpg +0 -0
- package/kb/references/thumbs/b88ee8d235.jpg +0 -0
- package/kb/references/thumbs/b8a4e5be8a.jpg +0 -0
- package/kb/references/thumbs/b8c85b661c.jpg +0 -0
- package/kb/references/thumbs/ba1b8e7435.jpg +0 -0
- package/kb/references/thumbs/ba9a593eed.jpg +0 -0
- package/kb/references/thumbs/baa7afc201.jpg +0 -0
- package/kb/references/thumbs/baf74398f7.jpg +0 -0
- package/kb/references/thumbs/bb3e947c10.jpg +0 -0
- package/kb/references/thumbs/bb4c1bb7c1.jpg +0 -0
- package/kb/references/thumbs/bbaa25cc8a.jpg +0 -0
- package/kb/references/thumbs/bc7e7f88cc.jpg +0 -0
- package/kb/references/thumbs/bc9d5b58f5.jpg +0 -0
- package/kb/references/thumbs/bcc99a51f7.jpg +0 -0
- package/kb/references/thumbs/bce13dd1c1.jpg +0 -0
- package/kb/references/thumbs/bd079a6130.jpg +0 -0
- package/kb/references/thumbs/bd2d70dda7.jpg +0 -0
- package/kb/references/thumbs/bd5895c5f2.jpg +0 -0
- package/kb/references/thumbs/bde8e31d62.jpg +0 -0
- package/kb/references/thumbs/be084e78f3.jpg +0 -0
- package/kb/references/thumbs/be94f170c8.jpg +0 -0
- package/kb/references/thumbs/bed33654f7.jpg +0 -0
- package/kb/references/thumbs/beeb9a0c18.jpg +0 -0
- package/kb/references/thumbs/bef42094dc.jpg +0 -0
- package/kb/references/thumbs/bf625496fa.jpg +0 -0
- package/kb/references/thumbs/bf771f1398.jpg +0 -0
- package/kb/references/thumbs/c0ddefa3d9.jpg +0 -0
- package/kb/references/thumbs/c0f01e536e.jpg +0 -0
- package/kb/references/thumbs/c1d592b678.jpg +0 -0
- package/kb/references/thumbs/c1e83e1b3e.jpg +0 -0
- package/kb/references/thumbs/c2168f8096.jpg +0 -0
- package/kb/references/thumbs/c249cd6b17.jpg +0 -0
- package/kb/references/thumbs/c2e3d4feed.jpg +0 -0
- package/kb/references/thumbs/c3cec01df1.jpg +0 -0
- package/kb/references/thumbs/c47bedb42d.jpg +0 -0
- package/kb/references/thumbs/c4b03b4680.jpg +0 -0
- package/kb/references/thumbs/c4e6d18ec3.jpg +0 -0
- package/kb/references/thumbs/c5477e2877.jpg +0 -0
- package/kb/references/thumbs/c566794674.jpg +0 -0
- package/kb/references/thumbs/c5b945afbb.jpg +0 -0
- package/kb/references/thumbs/c5e4659497.jpg +0 -0
- package/kb/references/thumbs/c622786702.jpg +0 -0
- package/kb/references/thumbs/c6250649ca.jpg +0 -0
- package/kb/references/thumbs/c6261a9526.jpg +0 -0
- package/kb/references/thumbs/c62e609076.jpg +0 -0
- package/kb/references/thumbs/c6602d3e85.jpg +0 -0
- package/kb/references/thumbs/c6c1a16e40.jpg +0 -0
- package/kb/references/thumbs/c77f932157.jpg +0 -0
- package/kb/references/thumbs/c79788f01e.jpg +0 -0
- package/kb/references/thumbs/c7a511ad1e.jpg +0 -0
- package/kb/references/thumbs/c7acfbc3c8.jpg +0 -0
- package/kb/references/thumbs/c7bb6d1bb8.jpg +0 -0
- package/kb/references/thumbs/c829eadcb9.jpg +0 -0
- package/kb/references/thumbs/c891fd9d85.jpg +0 -0
- package/kb/references/thumbs/c89f812ee3.jpg +0 -0
- package/kb/references/thumbs/c8a85b9f61.jpg +0 -0
- package/kb/references/thumbs/c8fdf85c9a.jpg +0 -0
- package/kb/references/thumbs/c961ac1031.jpg +0 -0
- package/kb/references/thumbs/c9fd3f88d8.jpg +0 -0
- package/kb/references/thumbs/ca0d6399c3.jpg +0 -0
- package/kb/references/thumbs/ca316c83e4.jpg +0 -0
- package/kb/references/thumbs/ca3b93aa0d.jpg +0 -0
- package/kb/references/thumbs/cb0596a85b.jpg +0 -0
- package/kb/references/thumbs/cb95a5c3ef.jpg +0 -0
- package/kb/references/thumbs/cbe238b656.jpg +0 -0
- package/kb/references/thumbs/cbf530e608.jpg +0 -0
- package/kb/references/thumbs/cc173494ec.jpg +0 -0
- package/kb/references/thumbs/ccb664bddf.jpg +0 -0
- package/kb/references/thumbs/ccf69d36cd.jpg +0 -0
- package/kb/references/thumbs/ccf759db42.jpg +0 -0
- package/kb/references/thumbs/cd2a285807.jpg +0 -0
- package/kb/references/thumbs/cd4a24a8ca.jpg +0 -0
- package/kb/references/thumbs/cdb3fe8938.jpg +0 -0
- package/kb/references/thumbs/cdce1b9bc6.jpg +0 -0
- package/kb/references/thumbs/cde3aa761a.jpg +0 -0
- package/kb/references/thumbs/ce9d5cd9c2.jpg +0 -0
- package/kb/references/thumbs/ceb01f8a34.jpg +0 -0
- package/kb/references/thumbs/cee15c98d0.jpg +0 -0
- package/kb/references/thumbs/cf6944ddae.jpg +0 -0
- package/kb/references/thumbs/d15dd21cd8.jpg +0 -0
- package/kb/references/thumbs/d1633bf2ed.jpg +0 -0
- package/kb/references/thumbs/d16a838000.jpg +0 -0
- package/kb/references/thumbs/d1cf87e9f0.jpg +0 -0
- package/kb/references/thumbs/d32511d913.jpg +0 -0
- package/kb/references/thumbs/d327e9dedd.jpg +0 -0
- package/kb/references/thumbs/d35bf6c85e.jpg +0 -0
- package/kb/references/thumbs/d37afc9d61.jpg +0 -0
- package/kb/references/thumbs/d3b66655c7.jpg +0 -0
- package/kb/references/thumbs/d40b4172b6.jpg +0 -0
- package/kb/references/thumbs/d4c40d1824.jpg +0 -0
- package/kb/references/thumbs/d4cb55a4b6.jpg +0 -0
- package/kb/references/thumbs/d4f0c30f7e.jpg +0 -0
- package/kb/references/thumbs/d51cce3ae5.jpg +0 -0
- package/kb/references/thumbs/d52948f9ba.jpg +0 -0
- package/kb/references/thumbs/d62bd3cba4.jpg +0 -0
- package/kb/references/thumbs/d668a21c92.jpg +0 -0
- package/kb/references/thumbs/d685072c52.jpg +0 -0
- package/kb/references/thumbs/d6d7b96093.jpg +0 -0
- package/kb/references/thumbs/d7cd874b21.jpg +0 -0
- package/kb/references/thumbs/d7e111736a.jpg +0 -0
- package/kb/references/thumbs/d88325f832.jpg +0 -0
- package/kb/references/thumbs/d9272ded76.jpg +0 -0
- package/kb/references/thumbs/d962e7c654.jpg +0 -0
- package/kb/references/thumbs/d97f000ee2.jpg +0 -0
- package/kb/references/thumbs/d9c1ae2543.jpg +0 -0
- package/kb/references/thumbs/d9ccb3cac8.jpg +0 -0
- package/kb/references/thumbs/da99019680.jpg +0 -0
- package/kb/references/thumbs/da9b8bc615.jpg +0 -0
- package/kb/references/thumbs/daafbee2c1.jpg +0 -0
- package/kb/references/thumbs/db0f11f143.jpg +0 -0
- package/kb/references/thumbs/db5dd367f5.jpg +0 -0
- package/kb/references/thumbs/db69677866.jpg +0 -0
- package/kb/references/thumbs/db87c1956e.jpg +0 -0
- package/kb/references/thumbs/dbb86d8bda.jpg +0 -0
- package/kb/references/thumbs/dbd3a8ff2a.jpg +0 -0
- package/kb/references/thumbs/dbdf4b2794.jpg +0 -0
- package/kb/references/thumbs/dd4c19b4b1.jpg +0 -0
- package/kb/references/thumbs/dd98d9f6fa.jpg +0 -0
- package/kb/references/thumbs/ddb00e3b6a.jpg +0 -0
- package/kb/references/thumbs/dde3541a5c.jpg +0 -0
- package/kb/references/thumbs/de2a4da502.jpg +0 -0
- package/kb/references/thumbs/de4c387a66.jpg +0 -0
- package/kb/references/thumbs/de5618fa82.jpg +0 -0
- package/kb/references/thumbs/de6bec2538.jpg +0 -0
- package/kb/references/thumbs/dea13cbb1f.jpg +0 -0
- package/kb/references/thumbs/deff9202aa.jpg +0 -0
- package/kb/references/thumbs/df12835f8d.jpg +0 -0
- package/kb/references/thumbs/df57acbb3d.jpg +0 -0
- package/kb/references/thumbs/df8265009e.jpg +0 -0
- package/kb/references/thumbs/dfc99a1e8e.jpg +0 -0
- package/kb/references/thumbs/dfc9fde460.jpg +0 -0
- package/kb/references/thumbs/e038348eee.jpg +0 -0
- package/kb/references/thumbs/e04c2ae1d5.jpg +0 -0
- package/kb/references/thumbs/e070345c43.jpg +0 -0
- package/kb/references/thumbs/e0a0c84d47.jpg +0 -0
- package/kb/references/thumbs/e0af1e6b9e.jpg +0 -0
- package/kb/references/thumbs/e1025942c4.jpg +0 -0
- package/kb/references/thumbs/e11b6f5b82.jpg +0 -0
- package/kb/references/thumbs/e1553de3fc.jpg +0 -0
- package/kb/references/thumbs/e162ebe7cd.jpg +0 -0
- package/kb/references/thumbs/e1f1e531d8.jpg +0 -0
- package/kb/references/thumbs/e20842e5c9.jpg +0 -0
- package/kb/references/thumbs/e24e7d949b.jpg +0 -0
- package/kb/references/thumbs/e2a3e5d10a.jpg +0 -0
- package/kb/references/thumbs/e2de02615a.jpg +0 -0
- package/kb/references/thumbs/e305dad7dd.jpg +0 -0
- package/kb/references/thumbs/e52e3ef97f.jpg +0 -0
- package/kb/references/thumbs/e570e92d06.jpg +0 -0
- package/kb/references/thumbs/e583932fb9.jpg +0 -0
- package/kb/references/thumbs/e5da3c038f.jpg +0 -0
- package/kb/references/thumbs/e657634af3.jpg +0 -0
- package/kb/references/thumbs/e67946e3e1.jpg +0 -0
- package/kb/references/thumbs/e69e0f3639.jpg +0 -0
- package/kb/references/thumbs/e6ebe66031.jpg +0 -0
- package/kb/references/thumbs/e7db9563c9.jpg +0 -0
- package/kb/references/thumbs/e84a4c3b7b.jpg +0 -0
- package/kb/references/thumbs/e84cf52c27.jpg +0 -0
- package/kb/references/thumbs/e8707cf6e8.jpg +0 -0
- package/kb/references/thumbs/e888890b40.jpg +0 -0
- package/kb/references/thumbs/e8a502b418.jpg +0 -0
- package/kb/references/thumbs/e8ba68371d.jpg +0 -0
- package/kb/references/thumbs/e9098f54cc.jpg +0 -0
- package/kb/references/thumbs/e9144deae9.jpg +0 -0
- package/kb/references/thumbs/e93e98d757.jpg +0 -0
- package/kb/references/thumbs/e9762dd435.jpg +0 -0
- package/kb/references/thumbs/e9db4544c8.jpg +0 -0
- package/kb/references/thumbs/e9ddffeacd.jpg +0 -0
- package/kb/references/thumbs/e9e2cf1d7e.jpg +0 -0
- package/kb/references/thumbs/ea1e23e623.jpg +0 -0
- package/kb/references/thumbs/ea41200f5e.jpg +0 -0
- package/kb/references/thumbs/eaf4916e1a.jpg +0 -0
- package/kb/references/thumbs/eb2c505fc8.jpg +0 -0
- package/kb/references/thumbs/eb47943693.jpg +0 -0
- package/kb/references/thumbs/eb4ffd6625.jpg +0 -0
- package/kb/references/thumbs/eb82ac0a4d.jpg +0 -0
- package/kb/references/thumbs/ebeb345ade.jpg +0 -0
- package/kb/references/thumbs/ec4e2aba0a.jpg +0 -0
- package/kb/references/thumbs/ed683bc9f7.jpg +0 -0
- package/kb/references/thumbs/ed9e236a84.jpg +0 -0
- package/kb/references/thumbs/ee45e1caea.jpg +0 -0
- package/kb/references/thumbs/ee50bbf2e7.jpg +0 -0
- package/kb/references/thumbs/eed6ad3b7b.jpg +0 -0
- package/kb/references/thumbs/eee247fd70.jpg +0 -0
- package/kb/references/thumbs/ef87b6cb99.jpg +0 -0
- package/kb/references/thumbs/ef87dccf04.jpg +0 -0
- package/kb/references/thumbs/ef941bba1e.jpg +0 -0
- package/kb/references/thumbs/effc14fb2c.jpg +0 -0
- package/kb/references/thumbs/f04aa5a191.jpg +0 -0
- package/kb/references/thumbs/f13f12485f.jpg +0 -0
- package/kb/references/thumbs/f16a5c0fd4.jpg +0 -0
- package/kb/references/thumbs/f1ba7a7a8f.jpg +0 -0
- package/kb/references/thumbs/f1bc4c9c19.jpg +0 -0
- package/kb/references/thumbs/f1ee827878.jpg +0 -0
- package/kb/references/thumbs/f21736aeff.jpg +0 -0
- package/kb/references/thumbs/f22bc41213.jpg +0 -0
- package/kb/references/thumbs/f266aaffcc.jpg +0 -0
- package/kb/references/thumbs/f2c0ed0d65.jpg +0 -0
- package/kb/references/thumbs/f32ac710fd.jpg +0 -0
- package/kb/references/thumbs/f32b697ff6.jpg +0 -0
- package/kb/references/thumbs/f39c883904.jpg +0 -0
- package/kb/references/thumbs/f3b9d55e6e.jpg +0 -0
- package/kb/references/thumbs/f3c1763e14.jpg +0 -0
- package/kb/references/thumbs/f40853fd43.jpg +0 -0
- package/kb/references/thumbs/f4fd07dc4d.jpg +0 -0
- package/kb/references/thumbs/f50b756ee5.jpg +0 -0
- package/kb/references/thumbs/f51272e9b3.jpg +0 -0
- package/kb/references/thumbs/f538895eee.jpg +0 -0
- package/kb/references/thumbs/f5d28081b5.jpg +0 -0
- package/kb/references/thumbs/f6046c9501.jpg +0 -0
- package/kb/references/thumbs/f62e4af316.jpg +0 -0
- package/kb/references/thumbs/f6f6bffeb8.jpg +0 -0
- package/kb/references/thumbs/f736e00af6.jpg +0 -0
- package/kb/references/thumbs/f7932da47d.jpg +0 -0
- package/kb/references/thumbs/f879e118ca.jpg +0 -0
- package/kb/references/thumbs/f88257215d.jpg +0 -0
- package/kb/references/thumbs/f88c45a6d7.jpg +0 -0
- package/kb/references/thumbs/f89a7b646e.jpg +0 -0
- package/kb/references/thumbs/f8a1e7a274.jpg +0 -0
- package/kb/references/thumbs/f9183cf2b6.jpg +0 -0
- package/kb/references/thumbs/f995de5ce9.jpg +0 -0
- package/kb/references/thumbs/f9ada2c3e1.jpg +0 -0
- package/kb/references/thumbs/f9d4616f89.jpg +0 -0
- package/kb/references/thumbs/f9f4307bb0.jpg +0 -0
- package/kb/references/thumbs/fa070122c7.jpg +0 -0
- package/kb/references/thumbs/fa29cc1369.jpg +0 -0
- package/kb/references/thumbs/fa791a4dab.jpg +0 -0
- package/kb/references/thumbs/fa8060509e.jpg +0 -0
- package/kb/references/thumbs/fafeed4003.jpg +0 -0
- package/kb/references/thumbs/fb1c024f38.jpg +0 -0
- package/kb/references/thumbs/fb77aa28b3.jpg +0 -0
- package/kb/references/thumbs/fb9f7f1966.jpg +0 -0
- package/kb/references/thumbs/fba8a8c2da.jpg +0 -0
- package/kb/references/thumbs/fce2754c36.jpg +0 -0
- package/kb/references/thumbs/fce2fb83df.jpg +0 -0
- package/kb/references/thumbs/fd4c51bb47.jpg +0 -0
- package/kb/references/thumbs/fd8c269817.jpg +0 -0
- package/kb/references/thumbs/fdb7b250ca.jpg +0 -0
- package/kb/references/thumbs/fe18088de8.jpg +0 -0
- package/kb/references/thumbs/fe4f742ba7.jpg +0 -0
- package/kb/references/thumbs/fe64742ce7.jpg +0 -0
- package/kb/references/thumbs/feb5d62161.jpg +0 -0
- package/kb/references/thumbs/fed21b3e98.jpg +0 -0
- package/kb/references/thumbs/fed2205951.jpg +0 -0
- package/kb/references/thumbs/ffdacf1715.jpg +0 -0
- package/kb/sections/_buttons.md +93 -0
- package/kb/sections/_finish.md +325 -0
- package/kb/sections/about-founder-note.md +85 -0
- package/kb/sections/about-team-roster.md +86 -0
- package/kb/sections/alternating-rows-live-tiles.md +110 -0
- package/kb/sections/annotated-product-shot.md +105 -0
- package/kb/sections/asymmetric-bento-dominant.md +114 -0
- package/kb/sections/before-after-features.md +104 -0
- package/kb/sections/before-after-repair.md +107 -0
- package/kb/sections/bento-lead-tile.md +112 -0
- package/kb/sections/book-a-slot-honest.md +116 -0
- package/kb/sections/capability-prompt-ledger.md +68 -0
- package/kb/sections/case-study-band.md +113 -0
- package/kb/sections/centred-stack-hero.md +107 -0
- package/kb/sections/closing-demo-final-state.md +81 -0
- package/kb/sections/closing-full-bleed-line-and-form.md +86 -0
- package/kb/sections/closing-result-previewed.md +88 -0
- package/kb/sections/closing-three-real-steps.md +87 -0
- package/kb/sections/command-reference-table.md +70 -0
- package/kb/sections/comparison-old-way-bars.md +88 -0
- package/kb/sections/comparison-same-task-two-ways.md +88 -0
- package/kb/sections/day-of-the-place.md +102 -0
- package/kb/sections/docs-reading-rail.md +88 -0
- package/kb/sections/editorial-columns-hero.md +107 -0
- package/kb/sections/editorial-essay-pull-quote.md +112 -0
- package/kb/sections/events-calendar-list.md +107 -0
- package/kb/sections/explorable-control-demo.md +102 -0
- package/kb/sections/faq-open-answers-editorial.md +85 -0
- package/kb/sections/faq-ruled-accordion-aside.md +87 -0
- package/kb/sections/footer-closing-scene.md +84 -0
- package/kb/sections/footer-editorial-sitemap.md +85 -0
- package/kb/sections/footer-minimal-credits.md +80 -0
- package/kb/sections/full-bleed-image-band.md +103 -0
- package/kb/sections/full-bleed-image-hero.md +105 -0
- package/kb/sections/gallery-first-hero.md +109 -0
- package/kb/sections/horizontal-scroll-strip.md +101 -0
- package/kb/sections/how-i-work-own-voice.md +111 -0
- package/kb/sections/how-it-works-in-place.md +109 -0
- package/kb/sections/impact-numbers-sourced.md +109 -0
- package/kb/sections/install-steps-per-agent.md +77 -0
- package/kb/sections/masonry-real-work.md +109 -0
- package/kb/sections/numbered-editorial-columns.md +105 -0
- package/kb/sections/object-first-hero.md +106 -0
- package/kb/sections/object-timeline.md +105 -0
- package/kb/sections/one-huge-number.md +100 -0
- package/kb/sections/one-person-story.md +103 -0
- package/kb/sections/order-ahead-ticket.md +119 -0
- package/kb/sections/press-strip-quoted.md +106 -0
- package/kb/sections/pricing-comparison-table-sticky.md +94 -0
- package/kb/sections/pricing-free-pro-upgrade-moment.md +85 -0
- package/kb/sections/pricing-plan-beside-product.md +88 -0
- package/kb/sections/pricing-plans-ledger.md +94 -0
- package/kb/sections/pricing-usage-calculator.md +93 -0
- package/kb/sections/printed-menu-card.md +110 -0
- package/kb/sections/process-happening.md +102 -0
- package/kb/sections/project-index-ruled.md +106 -0
- package/kb/sections/proof-logo-cloud-with-reasons.md +82 -0
- package/kb/sections/proof-measured-numbers.md +88 -0
- package/kb/sections/proof-output-wall.md +84 -0
- package/kb/sections/proof-single-honest-quote.md +81 -0
- package/kb/sections/resources-searchable-list.md +110 -0
- package/kb/sections/rooms-and-rates.md +107 -0
- package/kb/sections/ruled-facts-table.md +108 -0
- package/kb/sections/ruled-list-pinned-visual.md +107 -0
- package/kb/sections/scroll-scrubbed-product-demo.md +103 -0
- package/kb/sections/self-playing-run-demo.md +104 -0
- package/kb/sections/services-price-ledger.md +106 -0
- package/kb/sections/signup-form-with-next-steps.md +86 -0
- package/kb/sections/signup-waitlist-place-in-line.md +90 -0
- package/kb/sections/spec-sheet-features.md +108 -0
- package/kb/sections/split-hero-live-object.md +108 -0
- package/kb/sections/sticky-feature-narrative.md +104 -0
- package/kb/sections/todays-board-hero.md +112 -0
- package/kb/sections/touchable-tool-hero.md +111 -0
- package/kb/sections/typographic-statement-hero.md +99 -0
- package/kb/sections/visit-hours-map.md +110 -0
- package/kb/sections/ways-to-help-honest.md +115 -0
- package/kb/sources/design-reference.md +991 -0
- package/kb/sources/product-and-docs.md +37 -0
- package/kb/systems/1win/DESIGN.md +463 -0
- package/kb/systems/LICENSE-awesome-design-md +21 -0
- package/kb/systems/README.md +7 -0
- package/kb/systems/airbnb/DESIGN.md +545 -0
- package/kb/systems/airtable/DESIGN.md +554 -0
- package/kb/systems/aljazeera/DESIGN.md +594 -0
- package/kb/systems/apple/DESIGN.md +562 -0
- package/kb/systems/binance/DESIGN.md +634 -0
- package/kb/systems/bmw/DESIGN.md +544 -0
- package/kb/systems/bmw-m/DESIGN.md +503 -0
- package/kb/systems/bugatti/DESIGN.md +454 -0
- package/kb/systems/cal/DESIGN.md +542 -0
- package/kb/systems/categories.json +87 -0
- package/kb/systems/claude/DESIGN.md +589 -0
- package/kb/systems/clay/DESIGN.md +541 -0
- package/kb/systems/clickhouse/DESIGN.md +544 -0
- package/kb/systems/cohere/DESIGN.md +451 -0
- package/kb/systems/coinbase/DESIGN.md +570 -0
- package/kb/systems/composio/DESIGN.md +506 -0
- package/kb/systems/cursor/DESIGN.md +537 -0
- package/kb/systems/dell-1996/DESIGN.md +632 -0
- package/kb/systems/dji/DESIGN.md +882 -0
- package/kb/systems/elevenlabs/DESIGN.md +504 -0
- package/kb/systems/expo/DESIGN.md +526 -0
- package/kb/systems/ferrari/DESIGN.md +531 -0
- package/kb/systems/figma/DESIGN.md +578 -0
- package/kb/systems/framer/DESIGN.md +544 -0
- package/kb/systems/hashicorp/DESIGN.md +575 -0
- package/kb/systems/hp/DESIGN.md +670 -0
- package/kb/systems/ibm/DESIGN.md +550 -0
- package/kb/systems/intercom/DESIGN.md +546 -0
- package/kb/systems/jobright/DESIGN.md +525 -0
- package/kb/systems/kraken/DESIGN.md +125 -0
- package/kb/systems/lamborghini/DESIGN.md +288 -0
- package/kb/systems/linear.app/DESIGN.md +548 -0
- package/kb/systems/lovable/DESIGN.md +298 -0
- package/kb/systems/mastercard/DESIGN.md +365 -0
- package/kb/systems/mercury/DESIGN.md +568 -0
- package/kb/systems/meta/DESIGN.md +683 -0
- package/kb/systems/minimax/DESIGN.md +746 -0
- package/kb/systems/mintlify/DESIGN.md +852 -0
- package/kb/systems/miro/DESIGN.md +825 -0
- package/kb/systems/mistral.ai/DESIGN.md +773 -0
- package/kb/systems/mongodb/DESIGN.md +767 -0
- package/kb/systems/mydealz/DESIGN.md +551 -0
- package/kb/systems/nerdwallet/DESIGN.md +722 -0
- package/kb/systems/nike/DESIGN.md +575 -0
- package/kb/systems/nintendo-2001/DESIGN.md +649 -0
- package/kb/systems/notion/DESIGN.md +821 -0
- package/kb/systems/nvidia/DESIGN.md +640 -0
- package/kb/systems/ollama/DESIGN.md +539 -0
- package/kb/systems/opencode.ai/DESIGN.md +521 -0
- package/kb/systems/oracle/DESIGN.md +778 -0
- package/kb/systems/oura/DESIGN.md +616 -0
- package/kb/systems/pinterest/DESIGN.md +597 -0
- package/kb/systems/playstation/DESIGN.md +661 -0
- package/kb/systems/posthog/DESIGN.md +690 -0
- package/kb/systems/raycast/DESIGN.md +669 -0
- package/kb/systems/renault/DESIGN.md +589 -0
- package/kb/systems/replicate/DESIGN.md +616 -0
- package/kb/systems/resend/DESIGN.md +585 -0
- package/kb/systems/revolut/DESIGN.md +636 -0
- package/kb/systems/runwayml/DESIGN.md +244 -0
- package/kb/systems/sanity/DESIGN.md +357 -0
- package/kb/systems/sap/DESIGN.md +639 -0
- package/kb/systems/sentry/DESIGN.md +551 -0
- package/kb/systems/shopify/DESIGN.md +516 -0
- package/kb/systems/slack/DESIGN.md +482 -0
- package/kb/systems/spacex/DESIGN.md +363 -0
- package/kb/systems/spotify/DESIGN.md +246 -0
- package/kb/systems/starbucks/DESIGN.md +580 -0
- package/kb/systems/stripe/DESIGN.md +487 -0
- package/kb/systems/supabase/DESIGN.md +462 -0
- package/kb/systems/superhuman/DESIGN.md +448 -0
- package/kb/systems/tesla/DESIGN.md +286 -0
- package/kb/systems/theverge/DESIGN.md +339 -0
- package/kb/systems/together.ai/DESIGN.md +633 -0
- package/kb/systems/uber/DESIGN.md +636 -0
- package/kb/systems/vercel/DESIGN.md +736 -0
- package/kb/systems/vodafone/DESIGN.md +538 -0
- package/kb/systems/voltagent/DESIGN.md +521 -0
- package/kb/systems/warp/DESIGN.md +526 -0
- package/kb/systems/webflow/DESIGN.md +588 -0
- package/kb/systems/wired/DESIGN.md +497 -0
- package/kb/systems/wise/DESIGN.md +544 -0
- package/kb/systems/x.ai/DESIGN.md +465 -0
- package/kb/systems/zapier/DESIGN.md +537 -0
- package/kb/taste/garvit-by-job.md +46 -0
- package/kb/taste/garvit-portfolio.md +94 -0
- package/kb/universal/color-roles.md +26 -0
- package/kb/universal/copy.md +16 -0
- package/kb/universal/details.md +31 -0
- package/kb/universal/first-screen.md +30 -0
- package/kb/universal/fit-the-codebase.md +29 -0
- package/kb/universal/layout-width.md +28 -0
- package/kb/universal/motion-feedback.md +23 -0
- package/kb/universal/signature.md +29 -0
- package/kb/universal/states.md +17 -0
- package/kb/universal/type-app.md +33 -0
- package/kb/universal/type-marketing.md +28 -0
- package/package.json +36 -4
- package/scripts/pack-assets.mjs +48 -0
- package/skill/palate/SKILL.md +261 -0
- package/src/auth-recheck.mjs +4 -0
- package/src/auth.mjs +416 -0
- package/src/capture.mjs +182 -0
- package/src/catalog/classify.mjs +96 -0
- package/src/catalog/curated.mjs +128 -0
- package/src/catalog/index-build.mjs +67 -0
- package/src/catalog/literal.mjs +146 -0
- package/src/catalog/store.mjs +40 -0
- package/src/catalog/vibrant.mjs +126 -0
- package/src/check.mjs +93 -0
- package/src/concept.mjs +157 -0
- package/src/context.mjs +226 -0
- package/src/copy.mjs +188 -0
- package/src/devserver.mjs +135 -0
- package/src/fontgenre.mjs +44 -0
- package/src/guard-agents.mjs +213 -0
- package/src/guard.mjs +377 -0
- package/src/kb.mjs +91 -0
- package/src/look.mjs +312 -0
- package/src/loop/ambition.mjs +620 -0
- package/src/loop/animate.mjs +70 -0
- package/src/loop/artdirection.mjs +264 -0
- package/src/loop/bench.mjs +184 -0
- package/src/loop/benchpick.mjs +155 -0
- package/src/loop/blueprint.mjs +620 -0
- package/src/loop/board.html +180 -0
- package/src/loop/build.mjs +393 -0
- package/src/loop/buttons.mjs +413 -0
- package/src/loop/common.mjs +206 -0
- package/src/loop/cost.mjs +63 -0
- package/src/loop/craft.mjs +152 -0
- package/src/loop/craftchecks.mjs +148 -0
- package/src/loop/critique.mjs +393 -0
- package/src/loop/details.mjs +225 -0
- package/src/loop/direction.html +168 -0
- package/src/loop/direction.mjs +256 -0
- package/src/loop/directions.json +8 -0
- package/src/loop/explore.mjs +219 -0
- package/src/loop/fail.mjs +110 -0
- package/src/loop/fix.mjs +194 -0
- package/src/loop/floor.mjs +677 -0
- package/src/loop/forget.mjs +52 -0
- package/src/loop/gate.mjs +1053 -0
- package/src/loop/grid.html +123 -0
- package/src/loop/growth.mjs +118 -0
- package/src/loop/icons.mjs +109 -0
- package/src/loop/imagery.mjs +1280 -0
- package/src/loop/judge-api.mjs +245 -0
- package/src/loop/judge.mjs +167 -0
- package/src/loop/layouts.mjs +492 -0
- package/src/loop/library.mjs +82 -0
- package/src/loop/lookplan.mjs +182 -0
- package/src/loop/lookvec.mjs +645 -0
- package/src/loop/match.mjs +923 -0
- package/src/loop/matched.mjs +26 -0
- package/src/loop/myrefs.mjs +151 -0
- package/src/loop/pick.mjs +213 -0
- package/src/loop/picker.html +118 -0
- package/src/loop/plan.mjs +289 -0
- package/src/loop/polish.mjs +39 -0
- package/src/loop/research-learn.mjs +41 -0
- package/src/loop/research.mjs +1130 -0
- package/src/loop/rulereview.mjs +146 -0
- package/src/loop/rules-board.html +199 -0
- package/src/loop/rules.mjs +939 -0
- package/src/loop/similar.mjs +276 -0
- package/src/loop/states-source.mjs +258 -0
- package/src/loop/states.mjs +1547 -0
- package/src/loop/stats.mjs +78 -0
- package/src/loop/taste.mjs +81 -0
- package/src/loop/timeline.mjs +149 -0
- package/src/loop/variants.mjs +228 -0
- package/src/loop/vary.mjs +249 -0
- package/src/mcp/server.mjs +1246 -0
- package/src/motion.mjs +207 -0
- package/src/moves.mjs +242 -0
- package/src/novelty.mjs +116 -0
- package/src/page-ambition.js +181 -0
- package/src/page-craft.js +724 -0
- package/src/page-details.js +415 -0
- package/src/page-devices.js +365 -0
- package/src/page-fingerprint.js +281 -0
- package/src/page-gate.js +1307 -0
- package/src/page-look.js +698 -0
- package/src/page-metrics.js +78 -0
- package/src/page-principles.js +1167 -0
- package/src/page-rules.js +308 -0
- package/src/page-sections.js +211 -0
- package/src/page-states.js +703 -0
- package/src/paths.mjs +13 -0
- package/src/png.mjs +107 -0
- package/src/point/auto.mjs +224 -0
- package/src/point/locate.mjs +114 -0
- package/src/point/overlay.js +1516 -0
- package/src/point/server.mjs +1122 -0
- package/src/point/trail.mjs +219 -0
- package/src/pool.mjs +80 -0
- package/src/principles.mjs +279 -0
- package/src/refs.mjs +299 -0
- package/src/robots.mjs +145 -0
- package/src/sections.mjs +210 -0
- package/src/shoot.mjs +235 -0
- package/src/systems/apply.mjs +355 -0
- package/src/systems/load.mjs +251 -0
- package/src/systems/pick.mjs +213 -0
- package/templates/vite-react-tw/index.html +12 -0
- package/templates/vite-react-tw/package.json +25 -0
- package/templates/vite-react-tw/src/App.tsx +3 -0
- package/templates/vite-react-tw/src/index.css +1 -0
- package/templates/vite-react-tw/src/main.tsx +10 -0
- package/templates/vite-react-tw/tsconfig.app.json +26 -0
- package/templates/vite-react-tw/tsconfig.json +7 -0
- package/templates/vite-react-tw/tsconfig.node.json +23 -0
- package/templates/vite-react-tw/vite.config.ts +8 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>palate critique</title>
|
|
7
|
+
<link rel="icon" href="data:,">
|
|
8
|
+
<style>
|
|
9
|
+
:root { --bg: #f4f4f2; --fg: #191917; --muted: #6a6964; --line: #dcdbd5; --card: #ffffff; --accent: #191917; --on-accent: #ffffff; --ring: #3b6cff; --high: #c2410c; --medium: #a16207; --low: #6a6964; --idea: #3b6cff; --yes: #15803d; --no: #b91c1c; --on-state: #ffffff; }
|
|
10
|
+
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --bg: #141413; --fg: #ecebe6; --muted: #9c9b94; --line: #2c2b28; --card: #1c1c1a; --accent: #ecebe6; --on-accent: #141413; --high: #fb923c; --medium: #facc15; --low: #9c9b94; --idea: #8aa8ff; --yes: #4ade80; --no: #f87171; --on-state: #141413; } }
|
|
11
|
+
:root[data-theme="dark"] { --bg: #141413; --fg: #ecebe6; --muted: #9c9b94; --line: #2c2b28; --card: #1c1c1a; --accent: #ecebe6; --on-accent: #141413; --high: #fb923c; --medium: #facc15; --low: #9c9b94; --idea: #8aa8ff; --yes: #4ade80; --no: #f87171; --on-state: #141413; }
|
|
12
|
+
* { box-sizing: border-box; }
|
|
13
|
+
html, body { height: 100%; }
|
|
14
|
+
body { margin: 0; background: var(--bg); color: var(--fg); font: 14px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif; display: grid; grid-template-rows: auto 1fr auto; }
|
|
15
|
+
header.top { display: flex; align-items: baseline; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
|
|
16
|
+
h1 { font-size: 15px; font-weight: 600; margin: 0; }
|
|
17
|
+
.muted { color: var(--muted); }
|
|
18
|
+
main { min-height: 0; overflow: auto; padding: 14px 16px 24px; }
|
|
19
|
+
.group { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 16px; align-items: start; max-width: 1440px; margin: 0 auto 24px; }
|
|
20
|
+
.group > h2 { grid-column: 1 / -1; font-size: 13px; font-weight: 600; margin: 4px 0 -4px; color: var(--muted); }
|
|
21
|
+
.crop { position: sticky; top: 0; background: var(--card); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
|
|
22
|
+
.crop .tabs { display: flex; gap: 4px; padding: 6px; border-bottom: 1px solid var(--line); }
|
|
23
|
+
.shot { display: block; width: 100%; max-height: 70vh; overflow: auto; border: 0; padding: 0; background: var(--bg); cursor: zoom-in; }
|
|
24
|
+
.shot img { width: 100%; display: block; }
|
|
25
|
+
.cards { display: flex; flex-direction: column; gap: 10px; }
|
|
26
|
+
.card { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; display: grid; gap: 6px; transition: border-color .15s ease-out; }
|
|
27
|
+
.card:focus-within, .card:hover { border-color: var(--muted); }
|
|
28
|
+
.card[data-verdict="agree"] { border-color: color-mix(in srgb, var(--yes) 45%, var(--line)); }
|
|
29
|
+
.card[data-verdict="disagree"] { border-color: color-mix(in srgb, var(--no) 45%, var(--line)); }
|
|
30
|
+
.meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
|
|
31
|
+
.sev { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; color: var(--fg); text-transform: capitalize; }
|
|
32
|
+
.sev::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--low)); }
|
|
33
|
+
.rubric { margin-left: auto; font: 11px ui-monospace, monospace; }
|
|
34
|
+
.what { font-size: 15px; font-weight: 600; margin: 0; text-wrap: pretty; }
|
|
35
|
+
.why { margin: 0; color: var(--muted); text-wrap: pretty; }
|
|
36
|
+
.fix { margin: 0; text-wrap: pretty; }
|
|
37
|
+
.fix b { font-weight: 600; }
|
|
38
|
+
.actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 4px; }
|
|
39
|
+
button { font: inherit; border: 1px solid var(--line); background: var(--card); color: var(--fg); border-radius: 6px; padding: 7px 12px; cursor: pointer; transition: border-color .15s ease-out, background-color .15s ease-out; }
|
|
40
|
+
button:hover { border-color: var(--muted); }
|
|
41
|
+
button:active { transform: scale(.97); }
|
|
42
|
+
button.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
|
|
43
|
+
button.small { padding: 3px 8px; font-size: 12px; }
|
|
44
|
+
button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
|
|
45
|
+
button.agree[aria-pressed="true"] { background: var(--yes); border-color: var(--yes); color: var(--on-state); }
|
|
46
|
+
button.disagree[aria-pressed="true"] { background: var(--no); border-color: var(--no); color: var(--on-state); }
|
|
47
|
+
button:focus-visible, .shot:focus-visible, input:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
|
|
48
|
+
input.note { flex: 1; min-width: 180px; font: inherit; color: var(--fg); background: var(--bg); border: 1px solid var(--line); border-radius: 6px; padding: 6px 10px; }
|
|
49
|
+
input.note::placeholder { color: var(--muted); }
|
|
50
|
+
kbd { font: 11px ui-monospace, monospace; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px; padding: 0 4px; margin-left: 6px; color: inherit; opacity: .7; }
|
|
51
|
+
.bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 10px 16px; border-top: 1px solid var(--line); }
|
|
52
|
+
.bar[hidden] { display: none; }
|
|
53
|
+
dialog { border: 0; padding: 0; background: var(--card); color: var(--fg); width: min(1440px, 96vw); max-height: 94vh; border-radius: 10px; overflow: hidden; }
|
|
54
|
+
dialog::backdrop { background: rgba(0, 0, 0, .7); }
|
|
55
|
+
dialog .head { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--line); }
|
|
56
|
+
dialog .body { overflow: auto; max-height: calc(94vh - 56px); }
|
|
57
|
+
dialog img { width: 100%; display: block; }
|
|
58
|
+
.done { display: grid; place-items: center; text-align: center; min-height: 60vh; }
|
|
59
|
+
@media (max-width: 900px) { .group { grid-template-columns: 1fr; } .crop { position: static; } .shot { max-height: 40vh; } .hint { display: none; } }
|
|
60
|
+
@media (prefers-reduced-motion: reduce) { .card, button { transition: none; } button:active { transform: none; } }
|
|
61
|
+
</style>
|
|
62
|
+
</head>
|
|
63
|
+
<body>
|
|
64
|
+
<header class="top">
|
|
65
|
+
<h1>Do you agree with this critique?</h1>
|
|
66
|
+
<span class="muted" id="title"></span>
|
|
67
|
+
</header>
|
|
68
|
+
<main id="main"></main>
|
|
69
|
+
<div class="bar" id="bar">
|
|
70
|
+
<span class="muted" id="progress"></span>
|
|
71
|
+
<span class="muted hint">Mark each finding. Disagreements teach palate what you don't consider a problem.</span>
|
|
72
|
+
<span style="flex:1"></span>
|
|
73
|
+
<button class="primary" id="send">Send to the agent</button>
|
|
74
|
+
</div>
|
|
75
|
+
<dialog id="zoom" aria-labelledby="zoomTitle">
|
|
76
|
+
<div class="head"><b id="zoomTitle"></b><button id="zoomClose">Close</button></div>
|
|
77
|
+
<div class="body"><img id="zoomImg" alt=""></div>
|
|
78
|
+
</dialog>
|
|
79
|
+
<script>
|
|
80
|
+
const $ = (id) => document.getElementById(id);
|
|
81
|
+
const esc = (s) => String(s ?? "").replace(/[<>&"]/g, (c) => ({ "<": "<", ">": ">", "&": "&", '"': """ })[c]);
|
|
82
|
+
const ORDER = { high: 0, medium: 1, low: 2, idea: 3 };
|
|
83
|
+
let S;
|
|
84
|
+
|
|
85
|
+
async function load() {
|
|
86
|
+
S = await (await fetch("/api/state")).json();
|
|
87
|
+
$("title").textContent = `${S.project} · ${S.route}${S.title ? ` · ${S.title}` : ""} · ${S.findings.length} findings`;
|
|
88
|
+
if (S.finished) return finished();
|
|
89
|
+
// One group per section, in page order; the whole page first.
|
|
90
|
+
const groups = new Map();
|
|
91
|
+
for (const f of [...S.findings].sort((a, b) => a.sectionIndex - b.sectionIndex || ORDER[a.severity] - ORDER[b.severity])) {
|
|
92
|
+
if (!groups.has(f.sectionIndex)) groups.set(f.sectionIndex, { name: f.sectionName, items: [] });
|
|
93
|
+
groups.get(f.sectionIndex).items.push(f);
|
|
94
|
+
}
|
|
95
|
+
$("main").innerHTML = [...groups.entries()].map(([idx, g]) => {
|
|
96
|
+
const widths = ["1440", "390"].filter((w) => S.crops.includes(`${w}-${idx}`));
|
|
97
|
+
return `<section class="group" aria-label="${esc(g.name)}">
|
|
98
|
+
<h2>${idx ? `Section ${idx} · ` : ""}${esc(g.name)}</h2>
|
|
99
|
+
<div class="crop">${widths.length ? `
|
|
100
|
+
${widths.length > 1 ? `<div class="tabs">${widths.map((w, i) => `<button class="small" aria-pressed="${i === 0}" data-tab="${idx}" data-w="${w}">${w}px</button>`).join("")}</div>` : ""}
|
|
101
|
+
<button class="shot" data-zoom="${idx}" aria-label="View ${esc(g.name)} full size"><img id="img-${idx}" src="/img/${widths[0]}-${idx}.png" alt="${esc(g.name)} at ${widths[0]}px"></button>` : `<p class="muted" style="padding:12px;margin:0">No screenshot for this group.</p>`}
|
|
102
|
+
</div>
|
|
103
|
+
<div class="cards">${g.items.map(card).join("")}</div>
|
|
104
|
+
</section>`;
|
|
105
|
+
}).join("");
|
|
106
|
+
document.querySelectorAll("[data-tab]").forEach((b) => (b.onclick = () => {
|
|
107
|
+
document.querySelectorAll(`[data-tab="${b.dataset.tab}"]`).forEach((x) => x.setAttribute("aria-pressed", String(x === b)));
|
|
108
|
+
const img = $(`img-${b.dataset.tab}`);
|
|
109
|
+
img.src = `/img/${b.dataset.w}-${b.dataset.tab}.png`;
|
|
110
|
+
img.alt = img.alt.replace(/\d+px$/, `${b.dataset.w}px`);
|
|
111
|
+
}));
|
|
112
|
+
document.querySelectorAll("[data-zoom]").forEach((b) => (b.onclick = () => openZoom(b)));
|
|
113
|
+
document.querySelectorAll("[data-v]").forEach((b) => (b.onclick = () => mark(b.dataset.id, b.dataset.v)));
|
|
114
|
+
document.querySelectorAll("input.note").forEach((i) => {
|
|
115
|
+
let t;
|
|
116
|
+
i.oninput = () => { clearTimeout(t); t = setTimeout(() => post({ id: i.dataset.id, note: i.value }), 500); };
|
|
117
|
+
i.onblur = () => { clearTimeout(t); post({ id: i.dataset.id, note: i.value }); };
|
|
118
|
+
});
|
|
119
|
+
progress();
|
|
120
|
+
}
|
|
121
|
+
function card(f) {
|
|
122
|
+
const v = S.verdicts[f.id] ?? {};
|
|
123
|
+
return `<article class="card" tabindex="-1" id="c-${esc(f.id)}" data-id="${esc(f.id)}" data-verdict="${v.verdict ?? ""}">
|
|
124
|
+
<div class="meta"><span class="sev" style="--c: var(--${f.severity})">${f.severity}</span><span>${esc(f.id)}${f.width ? ` · ${f.width}px` : ""}</span>${f.rubric ? `<span class="rubric">${esc(f.rubric)}</span>` : ""}</div>
|
|
125
|
+
<p class="what">${esc(f.what)}</p>
|
|
126
|
+
${f.why ? `<p class="why">${esc(f.why)}</p>` : ""}
|
|
127
|
+
<p class="fix"><b>Fix:</b> ${esc(f.fix)}</p>
|
|
128
|
+
<div class="actions">
|
|
129
|
+
<button class="agree" data-id="${esc(f.id)}" data-v="agree" aria-pressed="${v.verdict === "agree"}">Agree<kbd>A</kbd></button>
|
|
130
|
+
<button class="disagree" data-id="${esc(f.id)}" data-v="disagree" aria-pressed="${v.verdict === "disagree"}">Disagree<kbd>D</kbd></button>
|
|
131
|
+
<input class="note" data-id="${esc(f.id)}" placeholder="Why? (optional)" aria-label="Note on ${esc(f.id)}" value="${esc(v.note ?? "")}">
|
|
132
|
+
</div>
|
|
133
|
+
</article>`;
|
|
134
|
+
}
|
|
135
|
+
const post = (b) => fetch("/api/verdict", { method: "POST", body: JSON.stringify(b) });
|
|
136
|
+
async function mark(id, verdict) {
|
|
137
|
+
const cur = S.verdicts[id]?.verdict;
|
|
138
|
+
const next = cur === verdict ? null : verdict;
|
|
139
|
+
S.verdicts[id] = { ...(S.verdicts[id] ?? {}), verdict: next };
|
|
140
|
+
const c = document.getElementById(`c-${id}`);
|
|
141
|
+
c.dataset.verdict = next ?? "";
|
|
142
|
+
c.querySelectorAll("[data-v]").forEach((b) => b.setAttribute("aria-pressed", String(b.dataset.v === next)));
|
|
143
|
+
progress();
|
|
144
|
+
await post({ id, verdict: next });
|
|
145
|
+
}
|
|
146
|
+
function progress() {
|
|
147
|
+
const n = S.findings.filter((f) => S.verdicts[f.id]?.verdict).length;
|
|
148
|
+
$("progress").textContent = `${n} of ${S.findings.length} marked`;
|
|
149
|
+
}
|
|
150
|
+
function openZoom(b) {
|
|
151
|
+
const img = $(`img-${b.dataset.zoom}`);
|
|
152
|
+
$("zoomTitle").textContent = img.alt;
|
|
153
|
+
$("zoomImg").src = img.src;
|
|
154
|
+
$("zoomImg").alt = img.alt;
|
|
155
|
+
$("zoom").showModal();
|
|
156
|
+
}
|
|
157
|
+
$("zoomClose").onclick = () => $("zoom").close();
|
|
158
|
+
$("send").onclick = async () => {
|
|
159
|
+
document.querySelectorAll("input.note").forEach((i) => (S.verdicts[i.dataset.id] = { ...(S.verdicts[i.dataset.id] ?? {}), note: i.value }));
|
|
160
|
+
await Promise.all([...document.querySelectorAll("input.note")].filter((i) => i.value).map((i) => post({ id: i.dataset.id, note: i.value })));
|
|
161
|
+
await fetch("/api/done", { method: "POST" });
|
|
162
|
+
finished();
|
|
163
|
+
};
|
|
164
|
+
function finished() {
|
|
165
|
+
const n = (v) => S.findings.filter((f) => S.verdicts[f.id]?.verdict === v).length;
|
|
166
|
+
$("bar").hidden = true;
|
|
167
|
+
$("main").innerHTML = `<div class="done"><div><h2>Sent: ${n("agree")} agreed, ${n("disagree")} disagreed.</h2><p class="muted">You can close this tab. The agent fixes what you agreed with, and palate remembers what you didn't.</p></div></div>`;
|
|
168
|
+
}
|
|
169
|
+
// A / D mark the finding you are on (hover or focus), unless you are typing a note.
|
|
170
|
+
let current = null;
|
|
171
|
+
document.addEventListener("mouseover", (e) => { const c = e.target.closest?.(".card"); if (c) current = c.dataset.id; });
|
|
172
|
+
document.addEventListener("focusin", (e) => { const c = e.target.closest?.(".card"); if (c) current = c.dataset.id; });
|
|
173
|
+
document.addEventListener("keydown", (e) => {
|
|
174
|
+
if ($("zoom").open || e.target.matches("input, textarea") || !current || e.metaKey || e.ctrlKey || e.altKey) return;
|
|
175
|
+
if (e.key === "a" || e.key === "d") { e.preventDefault(); mark(current, e.key === "a" ? "agree" : "disagree"); }
|
|
176
|
+
});
|
|
177
|
+
load();
|
|
178
|
+
</script>
|
|
179
|
+
</body>
|
|
180
|
+
</html>
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
// `palate build "<job>" --route /x [--direction <name>] [--refs a,b]`: build mode, palate's default. One brief
|
|
2
|
+
// for the real route (no variants): the user's rules, their references with their notes, the taste profile's
|
|
3
|
+
// section for this kind of screen, and the direction they chose if there was one. One builder follows it,
|
|
4
|
+
// then the finishing pass (shoot, details, critique on request), then the user points at what's wrong.
|
|
5
|
+
// `palate build --name <loop>` (or `palate build <winning route>`): after a variants pick, the brief that builds
|
|
6
|
+
// the winning sketch out into the full page. Sketches finish only the first screen and the centrepiece; the
|
|
7
|
+
// user picked from those, so only the winner is worth completing. The checks that were skipped while
|
|
8
|
+
// building (390, principles, details, motion) run here, on the one page that ships.
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
import { contextSummary } from "../context.mjs";
|
|
13
|
+
import { NOT_FOUND_ROUTE, isScaffold, routeFile } from "../look.mjs";
|
|
14
|
+
import { normalizeRoute } from "../shoot.mjs";
|
|
15
|
+
import { readJson, sessionDir } from "./common.mjs";
|
|
16
|
+
import { costLine, estimate, logCost } from "./cost.mjs";
|
|
17
|
+
import { kindWords, tasteFor } from "./craft.mjs";
|
|
18
|
+
import { chosenDirection, markBuilt } from "./direction.mjs";
|
|
19
|
+
import { recordInfluence, researchBuildLines } from "./research.mjs";
|
|
20
|
+
import { readLayouts } from "./layouts.mjs";
|
|
21
|
+
import { GATE, matchNote, otherLooks } from "./similar.mjs";
|
|
22
|
+
import { addRefs, refLines, rememberedRefs } from "./myrefs.mjs";
|
|
23
|
+
import { plan } from "./plan.mjs";
|
|
24
|
+
import { loopOfRoute, mark } from "./timeline.mjs";
|
|
25
|
+
import { kindTags, projectOf, routeTags, rulesBlock } from "./rules.mjs";
|
|
26
|
+
import { blueprintPlan, loadBlueprint } from "./blueprint.mjs";
|
|
27
|
+
import { moveBriefSafe } from "./research.mjs";
|
|
28
|
+
import { KB_ROOT } from "../paths.mjs";
|
|
29
|
+
import { matchedRoute } from "./matched.mjs";
|
|
30
|
+
|
|
31
|
+
const Sections = await import("../sections.mjs").catch(() => null);
|
|
32
|
+
const Imagery = await import("./imagery.mjs").catch(() => null);
|
|
33
|
+
|
|
34
|
+
const slash = (p) => String(p).replace(/\\/g, "/");
|
|
35
|
+
const KB = process.env.PALATE_KB ?? KB_ROOT;
|
|
36
|
+
const Buttons = await import("./buttons.mjs").catch(() => null);
|
|
37
|
+
// The page's button language in a few words, for the briefs ("" when the plan has none).
|
|
38
|
+
const buttonsLine = (bp) => (bp?.look?.buttons && Buttons ? ` (${Buttons.describeButtons(Buttons.resolveButtons(bp.look.buttons))})` : "");
|
|
39
|
+
|
|
40
|
+
// One brief per blueprint section: its job and content, its archetype's structure, finish and floor checks, the
|
|
41
|
+
// imagery it gets, and the craft files for its kind. Each section is built (and judged) on its own, so the
|
|
42
|
+
// last section gets the same attention as the hero.
|
|
43
|
+
function writeSectionBriefs(dir, session, bp, { route, chosen }) {
|
|
44
|
+
const out = path.join(session, "sections");
|
|
45
|
+
fs.rmSync(out, { recursive: true, force: true });
|
|
46
|
+
fs.mkdirSync(out, { recursive: true });
|
|
47
|
+
const tokens = path.join(bp.session, "tokens.tailwind.css");
|
|
48
|
+
const files = [];
|
|
49
|
+
const existing = bp.mode === "existing";
|
|
50
|
+
bp.sections.forEach((s, i) => {
|
|
51
|
+
// An existing page: only the sections being rebuilt or added get a brief.
|
|
52
|
+
if (existing && s.action !== "upgrade" && s.action !== "add") return;
|
|
53
|
+
const n = String(i + 1).padStart(2, "0");
|
|
54
|
+
const file = path.join(out, `${n}-${String(s.id ?? s.kind).replace(/[^a-z0-9]+/gi, "-")}.md`);
|
|
55
|
+
const arche = s.archetype && Sections?.sectionBrief ? Sections.sectionBrief(s.archetype) : null;
|
|
56
|
+
const checks = s.archetype && Sections?.floorChecks ? Sections.floorChecks(s.archetype) : [];
|
|
57
|
+
const img = Imagery?.imageryPlanLines ? [].concat(Imagery.imageryPlanLines([{ section: s.id, imagery: s.imagery }])) : [`- ${s.imagery}`];
|
|
58
|
+
const neighbours = [bp.sections[i - 1], bp.sections[i + 1]].filter(Boolean).map((x) => `${x.id} (${x.surface}, ${x.archetype ?? x.kind})`);
|
|
59
|
+
const brief = [
|
|
60
|
+
`# Section ${i + 1} of ${bp.sections.length}: ${s.id} (${s.kind})`,
|
|
61
|
+
"",
|
|
62
|
+
existing ? `${s.action === "upgrade" ? `Rebuild this existing section (now section ${s.current ?? "?"} of the page) in place, to the archetype below. Why: ${s.why ?? "it's below the bar"}. Keep its real content and the project's brand.` : "A new section on an existing page, in the project's own brand."}` : null,
|
|
63
|
+
`Part of the ${route} page for: ${bp.job ?? ""}. This section is built and judged on its own: an independent judge checks it against the questions at the end and against strong real sites. Give it the care the hero gets; a section that falls below the bar is rebuilt.`,
|
|
64
|
+
"",
|
|
65
|
+
"## Its job",
|
|
66
|
+
`- ${s.job}`,
|
|
67
|
+
`- Content (real, from the README; nothing invented): ${s.content ?? "see the README"}`,
|
|
68
|
+
`- Surface: ${s.surface} (the blueprint's \`${s.surface === "image" ? "image band" : s.surface}\` colour). Neighbours: ${neighbours.join(" and ") || "none"}; the change of surface between them is part of the rhythm.`,
|
|
69
|
+
s.signature ? `- **This section carries the signature moment**: ${chosen?.idea?.signature ? `${chosen.idea.signature.move}: ${chosen.idea.signature.moment}` : "the blueprint's signature"}. Mark its element with \`data-signature\`.` : null,
|
|
70
|
+
"",
|
|
71
|
+
"## Imagery and material",
|
|
72
|
+
...img,
|
|
73
|
+
`- Treatment for every photo on the page: ${bp.imagery?.treatment ?? "one treatment, the same everywhere"}.`,
|
|
74
|
+
"",
|
|
75
|
+
"## The system (use only these)",
|
|
76
|
+
existing && !fs.existsSync(tokens) ? "- The project's own tokens, fonts and components (its brand stays). Map the archetype's token names (--ink, --paper, --brand, --s-*, --r-*, --shadow-*, --hairline) to the project's own values where it has them." : null,
|
|
77
|
+
existing && !fs.existsSync(tokens) ? null : `- Tokens: ${slash(tokens)} (Tailwind v4 @theme; the plain-CSS twin is tokens.css beside it). Colours by role, display ${bp.system?.type?.display ?? "the project's"}, body ${bp.system?.type?.body ?? "the project's"}; numbers in the body face with tabular figures (class \`num\`); the buttons are \`.btn-primary\` and \`.btn-secondary\`, in the page's own button language${buttonsLine(bp)}; the names the archetype uses (--ink, --paper, --paper-2, --material, --brand, --s-1…--s-10, --t-lead, --t-h2, --r-sm/md/lg, --shadow-1/2/3, --hairline, --section) are defined in the same file.`,
|
|
78
|
+
`- Mood: ${(bp.spec?.mood ?? []).join(", ")}. Keep: ${(bp.spec?.truths ?? []).join("; ")}. Avoid: ${(bp.spec?.cliches ?? []).join("; ")}.`,
|
|
79
|
+
"",
|
|
80
|
+
...(arche ? ["## The archetype (build to this structure and finish)", arche, ""] : [`## Layout\n${s.archetype ?? s.shape ?? "as the blueprint says"}\n`]),
|
|
81
|
+
"## The finish, in short (all of it is already in the tokens file)",
|
|
82
|
+
"- Raised surfaces use --shadow-1 (resting), --shadow-2 (the product frame, the dominant tile) or --shadow-3 (floating); the first layer replaces a border, so no border as well.",
|
|
83
|
+
"- Hairlines are 1px --hairline (dividers, ruled lists) or --hairline-strong (inputs, table heads), never a grey hex.",
|
|
84
|
+
"- Radius nests: inner = outer − padding (--r-sm, --r-md, --r-lg); pills only for tags and toggles.",
|
|
85
|
+
`- Actions use the page's button language: .btn-primary (one per view) and .btn-secondary${buttonsLine(bp)}. Markup: ${Buttons?.markupHint?.(Buttons.resolveButtons(bp.look?.buttons)) || '<a class="btn-primary" href="…">Name the action</a>'}. Don't restyle them per section; numbers, times and prices use the body face with .num (tabular), never monospace.`,
|
|
86
|
+
"- Space follows --s-1…--s-10: heading to content --s-7, heading to lead --s-4/--s-5, more above a heading than below. No empty band over 160px.",
|
|
87
|
+
"- Display type: tracking −0.02 to −0.04em, text-wrap: balance; body text-wrap: pretty, measure 60–72ch.",
|
|
88
|
+
`- Anything else: ${slash(path.join(KB, "sections", "_finish.md"))} (look up only what you need).`,
|
|
89
|
+
s.signature && chosen?.idea?.signature?.move ? ["", "## The signature move's recipe", moveBriefSafe([chosen.idea.signature.move])].join("\n") : null,
|
|
90
|
+
"",
|
|
91
|
+
"",
|
|
92
|
+
"## Rules",
|
|
93
|
+
`- The user's rules in ${slash(path.join(session, "build.md"))} hold here too.`,
|
|
94
|
+
"- Build it as its own component file (the project's convention, e.g. src/components/sections/" + `${n}-${s.id}.tsx); touch no other section's file.`,
|
|
95
|
+
"- 390 matters as much as 1440: follow the archetype's phone layout; nothing taller than two screens that is just a stacked list.",
|
|
96
|
+
"- Never name palate, AI or the tools that built the page anywhere in its copy or credits: credits are for people, images and type.",
|
|
97
|
+
"- Logos and icons: placeholder company logos in mockups and fictional demos come from Hugeicons' free placeholder logos (hugeicons.com/logos, copy the SVG in), never as \"trusted by\" proof on a real product; icons are the project's own set, else Hugeicons free (MIT) or lucide, one set. Never draw a fake logo or a fake object.",
|
|
98
|
+
"",
|
|
99
|
+
"## Done when (the judge will ask exactly these; YES is good)",
|
|
100
|
+
...[
|
|
101
|
+
"Does this section look finished and deliberately designed, at the level of a strong product site?",
|
|
102
|
+
"Is every empty area clearly intentional (no dead band, no empty half, no mostly blank columns)?",
|
|
103
|
+
"Is there one clear focal point, with the rest a step quieter?",
|
|
104
|
+
"Is the content real and specific to this product?",
|
|
105
|
+
...checks,
|
|
106
|
+
].map((q) => `- ${q}`),
|
|
107
|
+
"Its own states belong to it: loading (a skeleton in the final layout), empty (a real next action), error (what happened, a retry), long names and many items, where they can happen in this section.",
|
|
108
|
+
"Its own details too: hover, focus-visible and pressed states on every control, inputs that aren't browser defaults, real avatars or deliberate monograms, numbers in tabular figures, alt text on every image. The page-wide pass only checks what you built.",
|
|
109
|
+
"",
|
|
110
|
+
"## How to work (fast, one pass)",
|
|
111
|
+
"- Read this brief and the archetype above; you don't need other files except the tokens and the README.",
|
|
112
|
+
"- Give the section's root element `id=\"" + s.id + "\"`: palate section and the quality gate find the section by that id.",
|
|
113
|
+
"- Report back in three lines at most (what you built, the check's result, anything left): the main build reads many reports at once.",
|
|
114
|
+
"- Build it in one pass, then check only your section: `palate section " + route + " " + s.id + "` (a crop at 1440 and 390 plus palate's floor checks for that section, in seconds). Fix what it shows once, then the last check with `--early`: `palate section " + route + " " + s.id + " --early` writes a packet for a fresh judge. Report done with that packet's path. Don't run full-page palate shoot: the main build runs it once for the whole page.",
|
|
115
|
+
"- If the main build sends you the early judge's verdict, fix exactly what it lists once, run `palate section " + route + " " + s.id + "`, and report done.",
|
|
116
|
+
]
|
|
117
|
+
.filter((l) => l != null)
|
|
118
|
+
.join("\n");
|
|
119
|
+
fs.writeFileSync(file, brief);
|
|
120
|
+
files.push({ file, id: s.id, kind: s.kind, n: i + 1 });
|
|
121
|
+
});
|
|
122
|
+
return files;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// The build brief's blueprint part: what was decided, and the order to build it in.
|
|
126
|
+
// duel: best of two for the hero (full builds only: it costs a builder and a judging round).
|
|
127
|
+
function blueprintLines(bp, files, { at, session, duel = false }) {
|
|
128
|
+
if (bp.mode === "existing") {
|
|
129
|
+
const by = (a) => bp.sections.filter((s) => s.action === a).map((s) => s.id);
|
|
130
|
+
return [
|
|
131
|
+
"## The blueprint: change this existing page in place (decided before code; follow it)",
|
|
132
|
+
`${slash(bp.file)}. ${bp.spec?.problems ? `What's below the bar now: ${[].concat(bp.spec.problems).join("; ")}.` : ""}`,
|
|
133
|
+
`- Keep exactly as they are: ${by("keep").join(", ") || "none"}. Rebuild: ${by("upgrade").join(", ") || "none"}. Add: ${by("add").join(", ") || "none"}. Remove: ${by("remove").join(", ") || "none"}.`,
|
|
134
|
+
`- New order: ${bp.sections.filter((s) => s.action !== "remove").map((s) => s.id).join(" → ")}`,
|
|
135
|
+
"",
|
|
136
|
+
"## Do it in this order",
|
|
137
|
+
`1. **Foundation (you):** the project's own tokens, fonts and components stay${fs.existsSync(path.join(bp.session, "tokens.css")) ? `; import ${slash(path.join(bp.session, "tokens.css"))} only for the finish tokens it adds (shadows, the archetypes' token names; the project keeps its own buttons), mapped to the project's own colours` : ""}. Remove the sections marked remove, put the rest in the new order.`,
|
|
138
|
+
`2. **The rebuilt and new sections in parallel**, one fresh subagent each, each owning its own component file: ${files.map((f) => `"Read ${slash(f.file)} and follow it exactly."`).join(" · ") || "(none)"}.`,
|
|
139
|
+
"3. **Stitch (you):** the rhythm between the kept and rebuilt sections, one spacing system, the phone layout of every changed section. Leave the kept sections alone.",
|
|
140
|
+
"",
|
|
141
|
+
];
|
|
142
|
+
}
|
|
143
|
+
const hero = files[0];
|
|
144
|
+
const rest = files.slice(1);
|
|
145
|
+
return [
|
|
146
|
+
"## The blueprint (decided before code; follow it)",
|
|
147
|
+
`${slash(bp.file)}: mood ${(bp.spec?.mood ?? []).join(", ")}; display ${bp.system.type.display}, body ${bp.system.type.body}; accent ${bp.system.colours?.accent ?? bp.system.colors?.accent}, material ${bp.system.colours?.material ?? bp.system.colors?.material}.`,
|
|
148
|
+
`Sections: ${bp.sections.map((s) => `${s.id} (${s.archetype ?? s.shape}, ${s.surface})`).join(" → ")}`,
|
|
149
|
+
...(bp.look
|
|
150
|
+
? [
|
|
151
|
+
`The look (this product's own; palate refused plans that repeat its recent pages): ${bp.look.ground} ground${bp.look.groundWhy ? ` (${bp.look.groundWhy})` : ""}, ${bp.look.texture ? "with texture" : "no texture"}, header ${bp.look.header}, ${bp.look.buttons ? `buttons ${Buttons?.describeButtons?.(Buttons.resolveButtons(bp.look.buttons)) ?? bp.look.buttons.language}` : `call to action ${bp.look.cta}`}, main object ${bp.look.frame}. Build exactly this: don't fall back to a cream page with grain, a logo-left header with a pill, or a framed card unless that is what it says.`,
|
|
152
|
+
]
|
|
153
|
+
: []),
|
|
154
|
+
"",
|
|
155
|
+
"## Build it in this order",
|
|
156
|
+
`1. **Foundation (you):** import ${slash(path.join(bp.session, "tokens.tailwind.css"))} after Tailwind (or tokens.css without Tailwind); load the two fonts (Google Fonts / @fontsource); fetch the imagery the section briefs list in one batch (\`palate imagery "<query> | <query> | …"\`, then one \`palate imagery pick\` for every id; \`palate texture …\`) and keep the credits; write the page shell for \`${at}\` with one component per section, in order.`,
|
|
157
|
+
`2. **Start every other section now, then build the hero (you):** launch step 3's subagents first, all at once and in the background, then build ${slash(hero.file)} yourself while they run (waiting for them before the hero cost a benchmark run 8 minutes). Then \`palate shoot ${at} --fold\` and fix what you see: the hero sets the bar the stitch pass holds every section to.${duel && bp.alternatives?.hero ? ` Best of two: a fresh subagent builds the blueprint's alternative hero (\`${bp.alternatives.hero}\`, read with \`palate sections show ${bp.alternatives.hero}\`, same job, content and tokens) as its own component, shown instead of the hero when the URL has \`?palate-alt=hero\`; then \`palate gate ${at} --duel hero\`, run its two packets with fresh subagents, \`--answers\`, and keep the winner.` : ""}`,
|
|
158
|
+
`3. **Every other section in parallel** (launched in step 2), one fresh subagent each, each owning its own component file: ${rest.map((f) => `"Read ${slash(f.file)} and follow it exactly."`).join(" · ")}. Each gets as much time as the hero did. **Judge each one as it lands:** when a builder reports its early-judge packet, give it to a fresh subagent at once (\"Read <packet> and follow it exactly.\"; never the builder), then \`palate section ${at} <id> --verdict\`; below the bar, send the verdict back to that builder (or a fresh one with its brief) for one fix while the others are still building. The hero too: \`palate section ${at} ${hero.id} --early\` after your fold shoot. The final gate still judges the whole page.`,
|
|
159
|
+
"4. **Stitch (you):** wire the sections in, then one pass over the whole page: the rhythm between surfaces, spacing that follows the system (at most two section spacings), one orchestrated entrance, nav anchors, and the phone layout of every section.",
|
|
160
|
+
"",
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
const walk = (d) => (fs.existsSync(d) ? fs.readdirSync(d, { withFileTypes: true }).flatMap((e) => (e.isDirectory() ? walk(path.join(d, e.name)) : [path.join(d, e.name)])) : []);
|
|
164
|
+
const slug = (s) => String(s).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").split("-").filter((w) => w.length > 2).slice(0, 3).join("-");
|
|
165
|
+
|
|
166
|
+
// Build mode: one brief for the real route. Returns the text the CLI and MCP print (the brief's path first).
|
|
167
|
+
// like: other projects the user asked this page to match (their look is then allowed; see similar.mjs).
|
|
168
|
+
export async function buildBrief(dir, job, { route, name, direction, refs = [], like = [], url, duel = Boolean(process.env.PALATE_DUEL) } = {}) {
|
|
169
|
+
if (!job?.trim()) throw new Error('Usage: palate build "<the job, in the user\'s words>" --route /x [--direction <name>] [--refs a.png,https://…]');
|
|
170
|
+
// The same reading of the request the triage makes (kind of screen, route), without logging a second triage.
|
|
171
|
+
const d = plan(dir, job, { route, name, mode: "build", log: false });
|
|
172
|
+
const r = d.route;
|
|
173
|
+
// A route built from the user's own design has its brief already: the fidelity contract, not palate's blueprint.
|
|
174
|
+
const userDesign = r ? matchedRoute(dir, r) : null;
|
|
175
|
+
if (userDesign) return [`# Build ${r}: from the user's own design`, "", `${r} matches ${userDesign.source.label}: the design is the spec, so there is no blueprint, no archetypes and no house-look check here.`, `Follow ${slash(userDesign.brief)}, then palate match --check --route ${r}.`].join("\n");
|
|
176
|
+
const found = r ? routeFile(dir, r) : null;
|
|
177
|
+
name ??= r === "/" ? "home" : r ? r.replace(/^\//, "").replace(/[^a-z0-9]+/gi, "-") : slug(job) || "screen";
|
|
178
|
+
// Never overwrite a variants loop of the same name.
|
|
179
|
+
const existing = readJson(path.join(dir, ".palate", "variants", name, "loop.json"), null);
|
|
180
|
+
if (existing && existing.mode !== "build") name = `${name}-build`;
|
|
181
|
+
const session = sessionDir(dir, name);
|
|
182
|
+
// A blueprint's events (its planning time) belong to this build's timeline; keep them.
|
|
183
|
+
for (const f of fs.existsSync(path.join(session, "blueprint.json")) ? ["build.md"] : ["events.jsonl", "build.md"]) fs.rmSync(path.join(session, f), { force: true });
|
|
184
|
+
const started = new Date().toISOString();
|
|
185
|
+
|
|
186
|
+
const given = refs.length ? await addRefs(refs, { job }) : [];
|
|
187
|
+
const userRefs = [...given, ...rememberedRefs(job, { exclude: given.map((x) => x.id) })];
|
|
188
|
+
const chosen = chosenDirection(dir, { name: direction, route: r });
|
|
189
|
+
const tags = kindTags({ screen: d.screen, kind: d.kind, route: r, words: `${name} ${job.slice(0, 160)}` });
|
|
190
|
+
const mine = rulesBlock(tags, { route: r, project: projectOf(dir) });
|
|
191
|
+
const taste = tasteFor(kindWords(d.screen, d.kind, name), { sections: 1, lean: true, project: path.basename(path.resolve(dir)) });
|
|
192
|
+
// ---- taste and similarity guards (similar.mjs): what the user asked to match, and their other projects' looks.
|
|
193
|
+
const likes = [...new Set([...like, ...matchNote(job, [...new Set(readLayouts().map((x) => x.project))])])];
|
|
194
|
+
const others = otherLooks(dir, d.kind === "app" ? "app" : "marketing", { like: likes });
|
|
195
|
+
let project = "";
|
|
196
|
+
try {
|
|
197
|
+
project = contextSummary(dir);
|
|
198
|
+
} catch {}
|
|
199
|
+
const target = found ? slash(found.file) : null;
|
|
200
|
+
const at = r ?? "<route>";
|
|
201
|
+
// Where a new route goes, from where the project's root page lives (src/app/page.tsx → src/app/x/page.tsx).
|
|
202
|
+
const home = !found && r ? routeFile(dir, "/") : null;
|
|
203
|
+
const homeDir = home ? slash(path.relative(dir, path.dirname(home.file))) : null;
|
|
204
|
+
const appRouter = Boolean(home) && /^\+?page\./.test(path.basename(home.file));
|
|
205
|
+
// A not-found page is the router's own file, not a route folder: app/not-found.tsx, pages/404.tsx, +error.svelte.
|
|
206
|
+
const notFound = home && NOT_FOUND_ROUTE.test(r) ? (home.file.endsWith(".svelte") ? "+error" : appRouter ? "not-found" : "404") : null;
|
|
207
|
+
const newFile = !home ? null : notFound ? `${homeDir}/${notFound}${path.extname(home.file)}` : appRouter ? `${homeDir}${r}/${path.basename(home.file)}` : `${homeDir}${r}${path.extname(home.file)}`;
|
|
208
|
+
|
|
209
|
+
// The blueprint (blueprint.mjs): the design decided before code. A new page without one gets the planner
|
|
210
|
+
// step first; with one, the build goes section by section.
|
|
211
|
+
// A blueprint belongs to its job: a later, different job on the same route plans again.
|
|
212
|
+
const saved = loadBlueprint(dir, { route: r, name });
|
|
213
|
+
const bp = saved && (!saved.job || saved.job.trim() === job.trim()) ? saved : null;
|
|
214
|
+
const needsBlueprint = !bp && !NOT_FOUND_ROUTE.test(r ?? "") && d.kind !== "app" && !process.env.PALATE_NO_BLUEPRINT;
|
|
215
|
+
if (needsBlueprint) {
|
|
216
|
+
// blueprintPlan decides whether the page really exists (a scaffold with an empty <main> is a new page).
|
|
217
|
+
const planned = await blueprintPlan(dir, job, { route: r, name, direction, url });
|
|
218
|
+
return [
|
|
219
|
+
`# Build ${at}: decide the design first`,
|
|
220
|
+
"",
|
|
221
|
+
planned.existing
|
|
222
|
+
? "This page exists. palate plans the change before code: what stays exactly as it is, which sections are rebuilt to a stronger archetype, what goes and what's added, in the project's own brand; then the gate checks the result against strong real sites and against the page as it is now."
|
|
223
|
+
: "This is a new page and there's no blueprint yet. palate builds new pages from a blueprint: the system, the imagery and one archetype per section, checked before any code (free generation drifts to one template and one flat colour).",
|
|
224
|
+
planned.text,
|
|
225
|
+
"",
|
|
226
|
+
`When palate blueprint passes, run palate build again with the same job: it builds the blueprint section by section.`,
|
|
227
|
+
].join("\n");
|
|
228
|
+
}
|
|
229
|
+
const sectionFiles = bp ? writeSectionBriefs(dir, session, bp, { route: at, chosen }) : [];
|
|
230
|
+
// A route file that is only a scaffold (or a blueprint planned it as a new page) is built, not changed in place.
|
|
231
|
+
const newPage = bp ? bp.mode !== "existing" : Boolean(found) && isScaffold(found.file);
|
|
232
|
+
|
|
233
|
+
const brief = [
|
|
234
|
+
mine.line,
|
|
235
|
+
"",
|
|
236
|
+
`# Build: ${job}`,
|
|
237
|
+
"",
|
|
238
|
+
...mine.lines,
|
|
239
|
+
`Project: ${slash(dir)}. Every fact, record and number comes from the project (its README and data). No invented customers, logos, testimonials, stats or reviews.`,
|
|
240
|
+
"",
|
|
241
|
+
"## Whose taste",
|
|
242
|
+
taste ? `From the user's own picks (the section for this kind of screen, and the rules that hold everywhere):\n\n${taste.trim()}` : "No taste profile yet: clarity first, one crafted touch at most.",
|
|
243
|
+
"",
|
|
244
|
+
// Taste is how the user judges; a look belongs to one product.
|
|
245
|
+
"Taste is how this user judges (clarity, restraint, real content, one crafted touch, their rules), not what their other projects looked like. This product's brand colour, type and layout come from its own name, users and direction.",
|
|
246
|
+
"",
|
|
247
|
+
...(others.length
|
|
248
|
+
? [
|
|
249
|
+
likes.length ? `## Your other projects (you may match ${likes.join(", ")}, as asked; don't repeat the rest)` : "## Not your other projects",
|
|
250
|
+
`\`palate shoot\` fails when this page is more than ${Math.round(GATE * 100)}% like any of these, or too close to a captured reference. Make different first-screen, colour and type decisions:`,
|
|
251
|
+
...others.map((o) => `- ${o.project} ${o.route}: ${o.look}`),
|
|
252
|
+
"",
|
|
253
|
+
]
|
|
254
|
+
: []),
|
|
255
|
+
...(chosen
|
|
256
|
+
? [
|
|
257
|
+
"## The direction the user chose",
|
|
258
|
+
`For the problem "${chosen.problem}", ${chosen.by === "auto" ? "palate picked (from the user's taste)" : "the user picked"} **${chosen.idea.name}**: ${chosen.idea.summary}`,
|
|
259
|
+
chosen.note ? `Their note (it beats the summary where they differ): "${chosen.note}"` : null,
|
|
260
|
+
`Rough wireframe (${chosen.idea.format}): keep its structure and its point, not its proportions.`,
|
|
261
|
+
"```" + (chosen.idea.format === "html" ? "html" : ""),
|
|
262
|
+
chosen.idea.wireframe,
|
|
263
|
+
"```",
|
|
264
|
+
"",
|
|
265
|
+
// From palate research: the art direction, its signature move's recipe, the abstract research notes and
|
|
266
|
+
// the "ideas, not expression" rule (research.mjs).
|
|
267
|
+
// With a blueprint, its tokens are the only system: the direction's starter tokens (which the blueprint
|
|
268
|
+
// refined) aren't printed, so build.md never shows two disagreeing palettes.
|
|
269
|
+
...(chosen.research ? researchBuildLines(dir, chosen, { tokens: !bp }) : []),
|
|
270
|
+
].filter((l) => l != null)
|
|
271
|
+
: []),
|
|
272
|
+
...(userRefs.length
|
|
273
|
+
? [
|
|
274
|
+
"## The user's own references (these come first)",
|
|
275
|
+
"What the user likes about a reference is what to take from it; what they dislike must not appear. Take the spirit (structure, density, type character, mood), never its text, logos, imagery or brand colours.",
|
|
276
|
+
...refLines(userRefs, { files: true }),
|
|
277
|
+
"",
|
|
278
|
+
]
|
|
279
|
+
: []),
|
|
280
|
+
...(bp ? blueprintLines(bp, sectionFiles, { at, session, duel }) : []),
|
|
281
|
+
"## What to build",
|
|
282
|
+
`One build, no variants: the real route \`${at}\`${target ? `, in ${target}` : ""}.`,
|
|
283
|
+
found && !newPage
|
|
284
|
+
? "- It exists: change it in place. Keep what the user didn't ask to change (its content, its sections and the parts that work); change what the job asks for, completely."
|
|
285
|
+
: found
|
|
286
|
+
? `- It is new: \`${target}\` is only a scaffold so far; build the page there (replace what it renders).`
|
|
287
|
+
: newFile
|
|
288
|
+
? `- It is new: create it in this project's routing convention: \`${newFile}\`.`
|
|
289
|
+
: `- It is new: create it in this project's routing convention (e.g. \`app${at === "<route>" ? "/<route>" : at}/page.tsx\` in Next.js, \`src/routes${at === "<route>" ? "/<route>" : at}.tsx\` in file routers).`,
|
|
290
|
+
"- Finished, not sketched: real content from the project, real state, every part the job needs. The details AI overlooks are the job too: loading, empty and error states, long text, many records, hover, focus and pressed states, motion that explains something.",
|
|
291
|
+
"- The project's tokens, fonts and components; no one-off values. Accessible: semantic structure, AA contrast, visible focus, reduced motion respected, nothing hidden waiting for scroll or JavaScript.",
|
|
292
|
+
"- Don't install packages without asking the user.",
|
|
293
|
+
"",
|
|
294
|
+
"## Finish (on this page, in this order)",
|
|
295
|
+
`1. \`palate finish ${at}\`: the finishing pass in one process, about a minute (the shoot at both widths with your rules and the similarity gate, every state, the small details, the motion check). Fix what it names: its "Your rules" line must read 0 fail and its similarity gate must pass (fix what it names yourself, never ask the user); build the missing states it lists, then \`palate states ${at} --verify\`; upgrade the generic small parts it lists. The section builders built their own states and details, so this is mostly a check.`,
|
|
296
|
+
`2. \`palate gate ${at}\`: the quality floor, judged by fresh subagents that didn't build the page (a builder grades its own work too kindly): palate's floor checks, a yes/no checklist per section, and a side-by-side against strong real sites in both orders. Run each judge packet it writes with its own fresh subagent, then \`palate gate ${at} --answers <dir>\`. Below the bar: palate writes one repair brief per failing section (up to three); run them in parallel, one fresh subagent each, then gate again (two repair rounds at most; a round that got worse is rolled back with --restore). No question to the user. Mark the signature moment's element with \`data-signature\`.`,
|
|
297
|
+
`3. \`palate critique ${at}\` only if the user asks for a review.`,
|
|
298
|
+
"4. `palate check` (it says \"Not done\" while a rule, the similarity gate or the quality gate fails) and the project's typecheck. Don't commit.",
|
|
299
|
+
"Tell the user the gate's verdict in one line, honestly: pass, or where it is still below the bar.",
|
|
300
|
+
"",
|
|
301
|
+
"## Then",
|
|
302
|
+
`Tell the user it's ready and offer \`palate point ${at}\`: they point at what's wrong in the running app, and you fix exactly that. When they reject something, \`palate fail ${at} "<their words>"\`. When they're done, \`palate taste learn\`.`,
|
|
303
|
+
project ? `\n## Project (palate context, short)\n${bp ? project.replace(/^- Fonts:.*$/m, `- Fonts: the blueprint's ${bp.system.type.display} and ${bp.system.type.body}: load them; they replace the system fonts.`) : project}` : "",
|
|
304
|
+
].join("\n");
|
|
305
|
+
|
|
306
|
+
const file = path.join(session, "build.md");
|
|
307
|
+
fs.writeFileSync(file, brief);
|
|
308
|
+
const cost = estimate({ mode: "build", briefs: [brief] });
|
|
309
|
+
fs.writeFileSync(
|
|
310
|
+
path.join(session, "loop.json"),
|
|
311
|
+
JSON.stringify({ name, job, title: job, kind: d.kind, screen: d.screen, mode: "build", stage: "build", planned: 1, route: r, target, tags, rules: mine.rules.map((x) => x.id), like: likes.length ? likes : undefined, userRefs: userRefs.map((x) => x.id), direction: chosen ? { name: chosen.name, idea: chosen.idea.name, research: chosen.research ?? undefined, signature: chosen.idea.signature ?? undefined } : null, cost, created: started }, null, 2),
|
|
312
|
+
);
|
|
313
|
+
mark(dir, name, "variants_start", { at: started });
|
|
314
|
+
mark(dir, name, "build_brief", { route: r });
|
|
315
|
+
logCost(dir, name, "build", cost);
|
|
316
|
+
if (chosen) markBuilt(chosen.session, name);
|
|
317
|
+
// Which research references fed this build (palate learns from it).
|
|
318
|
+
if (chosen?.research && !process.env.PALATE_NO_LOG) recordInfluence(dir, chosen, name);
|
|
319
|
+
return [
|
|
320
|
+
`# Build ${at}: one build, no variants`,
|
|
321
|
+
"",
|
|
322
|
+
`Brief: ${slash(file)}`,
|
|
323
|
+
`${mine.line} ${userRefs.length ? `${userRefs.length} of the user's references (${userRefs.filter((x) => x.likes?.length || x.dislikes?.length).length} with notes).` : "No saved references for this kind of screen."}${chosen ? ` Direction: ${chosen.idea.name}.` : ""}`,
|
|
324
|
+
costLine(cost),
|
|
325
|
+
`Build it yourself or with one subagent: "Read ${slash(file)} and follow it exactly." Then the finishing pass it lists, then offer palate point ${at}.`,
|
|
326
|
+
].join("\n");
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export function build(dir, { name, route } = {}) {
|
|
330
|
+
name ??= route ? loopOfRoute(dir, normalizeRoute(route)) : null;
|
|
331
|
+
if (!name) throw new Error(`No loop found for ${route}. Usage: palate build --name <loop>`);
|
|
332
|
+
const session = sessionDir(dir, name);
|
|
333
|
+
const meta = readJson(path.join(session, "loop.json"), null);
|
|
334
|
+
if (!meta) throw new Error(`No loop "${name}" in this project. Run palate variants first.`);
|
|
335
|
+
const result = readJson(path.join(session, "result.json"), null);
|
|
336
|
+
const winner = route ? normalizeRoute(route) : result?.ranking?.[0]?.wins ? result.ranking[0].route : null;
|
|
337
|
+
if (!winner) throw new Error(`No winner yet for "${name}". Run palate pick --name ${name} first, or name the route: palate build <route>.`);
|
|
338
|
+
const letter = winner.match(/-([a-z])\d+$/)?.[1];
|
|
339
|
+
const direction = (meta.directions ?? []).find((d) => d.letter === letter);
|
|
340
|
+
const briefFile = path.join(session, `brief-${letter}.md`);
|
|
341
|
+
const found = routeFile(dir, winner);
|
|
342
|
+
const folder = found && path.dirname(found.file) !== found.root ? path.dirname(found.file) : null;
|
|
343
|
+
const files = folder ? walk(folder) : found ? [found.file] : [];
|
|
344
|
+
const stubs = files.reduce((n, f) => n + (fs.readFileSync(f, "utf8").match(/palate: stub/g) ?? []).length, 0);
|
|
345
|
+
const mine = result?.ranking?.find((r) => r.route === winner);
|
|
346
|
+
const why = mine && Object.keys(mine.reasons ?? {}).length ? Object.keys(mine.reasons).join(", ") : null;
|
|
347
|
+
const others = (result?.ranking ?? []).filter((r) => r.route !== winner && Object.keys(r.reasons ?? {}).length);
|
|
348
|
+
|
|
349
|
+
// The user's rules apply to the whole page now, not only the first screen.
|
|
350
|
+
const yours = rulesBlock(meta.tags ?? (meta.vary ? routeTags(dir, winner) : kindTags({ screen: meta.screen, kind: meta.kind, words: name })), { route: meta.route, project: projectOf(dir) });
|
|
351
|
+
const brief = [
|
|
352
|
+
yours.line,
|
|
353
|
+
"",
|
|
354
|
+
`# Build out the winner: ${winner}`,
|
|
355
|
+
"",
|
|
356
|
+
...yours.lines,
|
|
357
|
+
`The user picked ${winner}${direction ? ` (direction: ${direction.name})` : ""} from sketches for: ${meta.job}`,
|
|
358
|
+
why ? `They said why: ${why}.` : null,
|
|
359
|
+
"",
|
|
360
|
+
"## Keep",
|
|
361
|
+
`- The first screen and the centrepiece exactly as they are: they are what the user chose. Don't restyle, re-space or "improve" them.`,
|
|
362
|
+
`- Source: ${files.map(slash).join(", ") || "the winner's route file"}.`,
|
|
363
|
+
fs.existsSync(briefFile) ? `- The sketch's brief still applies (taste, references, rules): ${slash(briefFile)}. Read its taste and rules; skip its "What to build".` : null,
|
|
364
|
+
"",
|
|
365
|
+
"## Build",
|
|
366
|
+
`- Complete every stubbed part (${stubs ? `${stubs} marked \`palate: stub\`` : "anything below the centrepiece that is only a heading and a line"}) to the same standard as the first screen, in the same direction: same type scale, spacing rhythm, colour roles and level of craft. Remove the stub markers.`,
|
|
367
|
+
"- Give the page every section the job needs, in a sensible order; real content from the project only.",
|
|
368
|
+
"- Vary the rhythm: not every section the same device (no kicker label or frame on every section).",
|
|
369
|
+
others.length ? `- One part of a runner-up may carry over if the user's reasons point to it: ${others.map((r) => `${r.route} (${Object.keys(r.reasons).join(", ")})`).join("; ")}.` : null,
|
|
370
|
+
"",
|
|
371
|
+
"## Check (on this page only: these were skipped while sketching)",
|
|
372
|
+
`1. \`palate shoot ${winner}\` (1440 and 390, full page, principles): open both, fix what it measures and what you see. Its "Your rules" line must read 0 fail and its similarity gate must pass.`,
|
|
373
|
+
`2. \`palate states ${winner}\`: build the missing states it lists, then \`palate states ${winner} --verify\`.`,
|
|
374
|
+
`3. \`palate details ${winner}\`: upgrade the generic small parts it lists.`,
|
|
375
|
+
`4. If the page moves: \`palate animate ${winner} --check\` (nothing hidden, no layout shift, reduced motion).`,
|
|
376
|
+
`5. \`palate gate ${winner}\`: the quality floor, judged by fresh subagents (run each packet it writes, then --answers); repair the one section it names, at most two rounds. No question to the user.`,
|
|
377
|
+
"6. The project's typecheck passes.",
|
|
378
|
+
"",
|
|
379
|
+
"## Then",
|
|
380
|
+
`- Move the page to its real route (the one the user asked for), delete every other ${name}-* variant route, and run \`palate polish <real route>\` and \`palate taste learn\`.`,
|
|
381
|
+
]
|
|
382
|
+
.filter((l) => l != null)
|
|
383
|
+
.join("\n");
|
|
384
|
+
const file = path.join(session, "build.md");
|
|
385
|
+
fs.writeFileSync(file, brief);
|
|
386
|
+
mark(dir, name, "build_brief", { route: winner });
|
|
387
|
+
return [
|
|
388
|
+
`# Build out ${winner}`,
|
|
389
|
+
"",
|
|
390
|
+
`Brief: ${slash(file)}`,
|
|
391
|
+
`Build it yourself or with one subagent: "Read ${slash(file)} and follow it exactly." One builder: the other variants are done.`,
|
|
392
|
+
].join("\n");
|
|
393
|
+
}
|