feat: updated Research page

This commit is contained in:
Musa 2025-12-11 18:59:32 -08:00
parent 73fce0cf18
commit 573744961d
26 changed files with 1186 additions and 254 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 332 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -0,0 +1,54 @@
<svg width="235" height="60" viewBox="0 0 235 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M43.5977 54.2294V20.8547H49.1754V25.6551H50.4555L49.1754 26.981C49.1754 24.9389 49.785 23.3387 51.0041 22.1805C52.2233 20.9918 53.8692 20.3975 55.9417 20.3975C58.4715 20.3975 60.4984 21.2661 62.0223 23.0035C63.5463 24.7408 64.3083 27.0724 64.3083 29.9984V36.8105C64.3083 38.7612 63.9578 40.468 63.2568 41.931C62.5862 43.3635 61.6261 44.476 60.3765 45.2685C59.1268 46.061 57.6486 46.4572 55.9417 46.4572C53.8692 46.4572 52.2233 45.8781 51.0041 44.7199C49.785 43.5312 49.1754 41.9158 49.1754 39.8737L50.4555 41.1995H49.1297L49.3125 47.1887V54.2294H43.5977ZM53.9301 41.5196C55.3931 41.5196 56.5361 41.0929 57.359 40.2394C58.182 39.386 58.5934 38.1668 58.5934 36.5819V30.2727C58.5934 28.6878 58.182 27.4687 57.359 26.6152C56.5361 25.7618 55.3931 25.3351 53.9301 25.3351C52.4976 25.3351 51.3699 25.7771 50.5469 26.661C49.724 27.5144 49.3125 28.7183 49.3125 30.2727V36.5819C49.3125 38.1364 49.724 39.3555 50.5469 40.2394C51.3699 41.0929 52.4976 41.5196 53.9301 41.5196ZM81.3893 46C79.7434 46 78.2956 45.6647 77.046 44.9942C75.8268 44.3236 74.8667 43.3788 74.1657 42.1596C73.4647 40.91 73.1142 39.4775 73.1142 37.8621V17.7915H65.0676V12.6253H78.829V37.8621C78.829 38.7764 79.0881 39.5079 79.6062 40.0566C80.1548 40.5747 80.8863 40.8338 81.8007 40.8338H89.39V46H81.3893ZM98.5159 46.4572C95.9252 46.4572 93.8831 45.7714 92.3896 44.3998C90.8961 43.0283 90.1494 41.1843 90.1494 38.8679C90.1494 36.3991 90.9723 34.4941 92.6182 33.153C94.2641 31.8119 96.5958 31.1414 99.6132 31.1414H105.877V28.9926C105.877 27.7734 105.48 26.8286 104.688 26.158C103.896 25.457 102.814 25.1065 101.442 25.1065C100.192 25.1065 99.156 25.3808 98.3331 25.9295C97.5101 26.4781 97.0225 27.2248 96.8701 28.1697H91.2924C91.5667 25.7923 92.6335 23.9026 94.4927 22.5005C96.3519 21.0985 98.7293 20.3975 101.625 20.3975C104.703 20.3975 107.126 21.1747 108.894 22.7291C110.692 24.2531 111.592 26.3257 111.592 28.9469V46H106.06V41.611H105.145L106.06 40.3766C106.06 42.2358 105.374 43.7141 104.002 44.8113C102.631 45.9086 100.802 46.4572 98.5159 46.4572ZM100.39 42.1596C102.006 42.1596 103.316 41.7482 104.322 40.9252C105.359 40.1023 105.877 39.0355 105.877 37.7249V34.6617H99.7046C98.5464 34.6617 97.6168 34.997 96.9158 35.6676C96.2148 36.3381 95.8642 37.222 95.8642 38.3192C95.8642 39.5079 96.2605 40.4528 97.0529 41.1538C97.8759 41.8244 98.9884 42.1596 100.39 42.1596ZM114.865 46V20.8547H120.443V25.6551H121.998L120.443 26.981C120.443 24.9084 121.037 23.293 122.226 22.1348C123.445 20.9766 125.106 20.3975 127.209 20.3975C129.678 20.3975 131.644 21.2204 133.107 22.8663C134.601 24.5122 135.347 26.7219 135.347 29.4955V46H129.633V30.0899C129.633 28.5659 129.236 27.3925 128.444 26.5695C127.651 25.7466 126.539 25.3351 125.106 25.3351C123.704 25.3351 122.592 25.7618 121.769 26.6152C120.976 27.4687 120.58 28.6878 120.58 30.2727V46H114.865ZM148.817 46.4115C146.683 46.4115 144.824 46.0152 143.239 45.2228C141.684 44.3998 140.465 43.2569 139.581 41.7939C138.728 40.3004 138.301 38.5478 138.301 36.5362V30.3185C138.301 28.3068 138.728 26.5695 139.581 25.1065C140.465 23.613 141.684 22.4701 143.239 21.6776C144.824 20.8547 146.683 20.4432 148.817 20.4432C150.981 20.4432 152.84 20.8547 154.394 21.6776C155.949 22.4701 157.153 23.613 158.006 25.1065C158.89 26.5695 159.332 28.2916 159.332 30.2727V36.5362C159.332 38.5478 158.89 40.3004 158.006 41.7939C157.153 43.2569 155.949 44.3998 154.394 45.2228C152.84 46.0152 150.981 46.4115 148.817 46.4115ZM148.817 41.4281C150.341 41.4281 151.514 41.0167 152.337 40.1937C153.19 39.3403 153.617 38.1211 153.617 36.5362V30.3185C153.617 28.7031 153.19 27.4839 152.337 26.661C151.514 25.838 150.341 25.4265 148.817 25.4265C147.323 25.4265 146.15 25.838 145.296 26.661C144.443 27.4839 144.016 28.7031 144.016 30.3185V36.5362C144.016 38.1211 144.443 39.3403 145.296 40.1937C146.15 41.0167 147.323 41.4281 148.817 41.4281ZM165.258 33.5645V28.2611H179.888V33.5645H165.258ZM200.443 46V39.3708H185.585V31.0957L198.431 12.6253H204.832L191.071 32.6044V34.3417H200.443V26.7981H206.158V46H200.443ZM222.233 46.4572C220.161 46.4572 218.515 45.8781 217.295 44.7199C216.076 43.5312 215.467 41.9158 215.467 39.8737L216.747 41.1995H215.467V46H209.889V12.6253H215.604V19.666L215.421 25.6551H216.747L215.467 26.981C215.467 24.9389 216.076 23.3387 217.295 22.1805C218.515 20.9918 220.161 20.3975 222.233 20.3975C224.763 20.3975 226.79 21.2661 228.314 23.0035C229.838 24.7408 230.6 27.0877 230.6 30.0441V36.8562C230.6 39.7822 229.838 42.1139 228.314 43.8512C226.79 45.5885 224.763 46.4572 222.233 46.4572ZM220.221 41.5196C221.684 41.5196 222.827 41.0929 223.65 40.2394C224.473 39.386 224.885 38.1668 224.885 36.5819V30.2727C224.885 28.6878 224.473 27.4687 223.65 26.6152C222.827 25.7618 221.684 25.3351 220.221 25.3351C218.789 25.3351 217.661 25.7771 216.838 26.661C216.015 27.5144 215.604 28.7183 215.604 30.2727V36.5819C215.604 38.1364 216.015 39.3555 216.838 40.2394C217.661 41.0929 218.789 41.5196 220.221 41.5196Z" fill="#7780D9" style="fill:#7780D9;fill:color(display-p3 0.4667 0.5020 0.8510);fill-opacity:1;"/>
<rect y="13.2812" width="33.6133" height="33.6133" fill="#7780D9" style="fill:#7780D9;fill:color(display-p3 0.4667 0.5020 0.8510);fill-opacity:1;"/>
<rect x="2.58563" y="15.8672" width="28.442" height="28.442" fill="#B9BFFF" style="fill:#B9BFFF;fill:color(display-p3 0.7246 0.7499 1.0000);fill-opacity:1;"/>
<path d="M3.87848 17.1602H6.46411V19.7458H3.87848V17.1602Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M3.87848 21.0381H6.46411V23.6237H3.87848V21.0381Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M3.87848 24.917H6.46411V27.5026H3.87848V24.917Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M3.87848 28.7949H6.46411V31.3806H3.87848V28.7949Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M3.87848 32.6738H6.46411V35.2595H3.87848V32.6738Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M3.87848 36.5518H6.46411V39.1374H3.87848V36.5518Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M3.87848 40.4307H6.46411V43.0163H3.87848V40.4307Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15.5138 17.1602H18.0994V19.7458H15.5138V17.1602Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M15.5138 21.0381H18.0994V23.6237H15.5138V21.0381Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M15.5138 24.917H18.0994V27.5026H15.5138V24.917Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M15.5138 28.7949H18.0994V31.3806H15.5138V28.7949Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15.5138 32.6738H18.0994V35.2595H15.5138V32.6738Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15.5138 36.5518H18.0994V39.1374H15.5138V36.5518Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15.5138 40.4307H18.0994V43.0163H15.5138V40.4307Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M7.7569 17.1602H10.3425V19.7458H7.7569V17.1602Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M7.7569 21.0381H10.3425V23.6237H7.7569V21.0381Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M7.7569 24.917H10.3425V27.5026H7.7569V24.917Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M7.7569 28.7949H10.3425V31.3806H7.7569V28.7949Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M7.7569 32.6738H10.3425V35.2595H7.7569V32.6738Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M7.7569 36.5518H10.3425V39.1374H7.7569V36.5518Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M7.7569 40.4307H10.3425V43.0163H7.7569V40.4307Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M19.3923 17.1602H21.9779V19.7458H19.3923V17.1602Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M19.3923 21.0381H21.9779V23.6237H19.3923V21.0381Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M19.3923 24.917H21.9779V27.5026H19.3923V24.917Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M19.3923 28.7949H21.9779V31.3806H19.3923V28.7949Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M19.3923 32.6738H21.9779V35.2595H19.3923V32.6738Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M19.3923 36.5518H21.9779V39.1374H19.3923V36.5518Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M19.3923 40.4307H21.9779V43.0163H19.3923V40.4307Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M11.6354 17.1602H14.221V19.7458H11.6354V17.1602Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M11.6354 21.0381H14.221V23.6237H11.6354V21.0381Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M11.6354 24.917H14.221V27.5026H11.6354V24.917Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M11.6354 28.7949H14.221V31.3806H11.6354V28.7949Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M11.6354 32.6738H14.221V35.2595H11.6354V32.6738Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M11.6354 36.5518H14.221V39.1374H11.6354V36.5518Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M11.6354 40.4307H14.221V43.0163H11.6354V40.4307Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M23.2707 17.1602H25.8563V19.7458H23.2707V17.1602Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M23.2707 21.0381H25.8563V23.6237H23.2707V21.0381Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M23.2707 24.917H25.8563V27.5026H23.2707V24.917Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M23.2707 28.7949H25.8563V31.3806H23.2707V28.7949Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M23.2707 32.6738H25.8563V35.2595H23.2707V32.6738Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M23.2707 36.5518H25.8563V39.1374H23.2707V36.5518Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M23.2707 40.4307H25.8563V43.0163H23.2707V40.4307Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M27.1492 17.1602H29.7348V19.7458H27.1492V17.1602Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M27.1492 21.0381H29.7348V23.6237H27.1492V21.0381Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M27.1492 24.917H29.7348V27.5026H27.1492V24.917Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M27.1492 28.7949H29.7348V31.3806H27.1492V28.7949Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M27.1492 32.6738H29.7348V35.2595H27.1492V32.6738Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M27.1492 36.5518H29.7348V39.1374H27.1492V36.5518Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M27.1492 40.4307H29.7348V43.0163H27.1492V40.4307Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,53 @@
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="26" height="26" fill="#7780D9" style="fill:#7780D9;fill:color(display-p3 0.4667 0.5020 0.8510);fill-opacity:1;"/>
<rect x="2" y="2" width="22" height="22" fill="#B9BFFF" style="fill:#B9BFFF;fill:color(display-p3 0.7246 0.7499 1.0000);fill-opacity:1;"/>
<path d="M3 3H5V5H3V3Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M3 6H5V8H3V6Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M3 9H5V11H3V9Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M3 12H5V14H3V12Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M3 15H5V17H3V15Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M3 18H5V20H3V18Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M3 21H5V23H3V21Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M12 3H14V5H12V3Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M12 6H14V8H12V6Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M12 9H14V11H12V9Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M12 12H14V14H12V12Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M12 15H14V17H12V15Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M12 18H14V20H12V18Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M12 21H14V23H12V21Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M6 3H8V5H6V3Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M6 6H8V8H6V6Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M6 9H8V11H6V9Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M6 12H8V14H6V12Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M6 15H8V17H6V15Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M6 18H8V20H6V18Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M6 21H8V23H6V21Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15 3H17V5H15V3Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M15 6H17V8H15V6Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M15 9H17V11H15V9Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15 12H17V14H15V12Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15 15H17V17H15V15Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15 18H17V20H15V18Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M15 21H17V23H15V21Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M9 3H11V5H9V3Z" fill="#B0B7FF" style="fill:#B0B7FF;fill:color(display-p3 0.6897 0.7182 1.0000);fill-opacity:1;"/>
<path d="M9 6H11V8H9V6Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M9 9H11V11H9V9Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M9 12H11V14H9V12Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M9 15H11V17H9V15Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M9 18H11V20H9V18Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M9 21H11V23H9V21Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M18 3H20V5H18V3Z" fill="#ABB2FA" style="fill:#ABB2FA;fill:color(display-p3 0.6706 0.6990 0.9799);fill-opacity:1;"/>
<path d="M18 6H20V8H18V6Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M18 9H20V11H18V9Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M18 12H20V14H18V12Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M18 15H20V17H18V15Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M18 18H20V20H18V18Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M18 21H20V23H18V21Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M21 3H23V5H21V3Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M21 6H23V8H21V6Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M21 9H23V11H21V9Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M21 12H23V14H21V12Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M21 15H23V17H21V15Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M21 18H23V20H21V18Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
<path d="M21 21H23V23H21V21Z" fill="#969FF4" style="fill:#969FF4;fill:color(display-p3 0.5882 0.6220 0.9566);fill-opacity:1;"/>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 102 KiB

View file

@ -0,0 +1,20 @@
"use client";
import React from "react";
import { ResearchHero, ResearchGrid, ResearchTimeline, ResearchCTA, ResearchCapabilities, ResearchBenchmarks, ResearchFamily } from "@/components/research";
import { UnlockPotentialSection } from "@/components/UnlockPotentialSection";
export default function ResearchPage() {
return (
<>
<ResearchHero />
<ResearchGrid />
<ResearchTimeline />
<ResearchCTA />
<ResearchCapabilities />
<ResearchBenchmarks />
{/* <ResearchFamily /> */}
<UnlockPotentialSection variant="transparent" />
</>
);
}

View file

@ -5,12 +5,15 @@ import { NetworkAnimation } from "./NetworkAnimation";
export function Hero() {
return (
<section className="relative pt-8 sm:pt-12 lg:pt-1 pb-6 px-4 sm:px-6 lg:px-8">
<div className="hidden lg:block">
<NetworkAnimation />
</div>
<div className="max-w-[81rem] mx-auto relative z-10">
<div className="max-w-3xl mb-6 sm:mb-4">
<section className="relative pt-8 sm:pt-12 lg:pt-1 pb-6 px-4 sm:px-6 lg:px-8 overflow-hidden">
<div className="max-w-[81rem] mx-auto relative">
<div className="hidden lg:block absolute inset-0 pointer-events-none ">
<NetworkAnimation />
</div>
<div className="lg:hidden absolute inset-0 pointer-events-none">
<NetworkAnimation className="!w-[300px] !h-[300px] left-82! top-1! opacity-90! " />
</div>
<div className="max-w-3xl mb-6 sm:mb-4 relative z-10">
{/* Version Badge */}
<div className="mb-4 sm:mb-6">
<div className="inline-flex flex-wrap items-center gap-1.5 sm:gap-2 px-3 sm:px-4 py-1 rounded-full bg-[rgba(185,191,255,0.4)] border border-[var(--secondary)] shadow backdrop-blur">
@ -30,7 +33,7 @@ export function Hero() {
</div>
{/* Main Heading */}
<h1 className="text-4xl sm:text-4xl md:text-5xl lg:text-7xl font-normal leading-tight tracking-tighter text-black mb-4 sm:mb-6 flex flex-col gap-0 sm:-space-y-2 lg:-space-y-3">
<h1 className="text-4xl sm:text-4xl md:text-5xl lg:text-7xl font-normal leading-tight tracking-tighter text-black flex flex-col gap-0 sm:-space-y-2 lg:-space-y-3">
<span className="font-sans">Delivery infrastructure </span>
<span className="font-sans font-medium text-[var(--secondary)]">
for agentic apps
@ -39,13 +42,14 @@ export function Hero() {
</div>
{/* Subheading with CTA Buttons */}
<div className="max-w-7xl flex flex-col lg:flex-row lg:items-end lg:justify-between gap-6">
<p className="text-base sm:text-lg md:text-xl lg:text-2xl font-sans font-[400] tracking-[-1.2px] sm:tracking-[-1.82px]! text-black max-w-4xl">
Build agents faster, and deliver them reliably to prod by offloading plumbing work in AI
<div className="max-w-7xl relative z-10">
<p className="text-base sm:text-lg md:text-xl lg:text-2xl font-sans font-[400] tracking-[-1.2px] sm:tracking-[-1.82px]! text-black max-w-70 sm:max-w-2xl mb-6">
Build agents faster, and deliver them reliably to production -
by offloading the plumbing work in building agentic applications.
</p>
{/* CTA Buttons */}
<div className="mb-0.5 flex flex-col sm:flex-row items-stretch sm:items-center gap-3 sm:gap-4 w-full sm:w-auto lg:justify-end">
<div className="flex flex-col sm:flex-row items-stretch sm:items-start gap-3 sm:gap-4">
<Button asChild className="w-full sm:w-auto">
<Link href="/get-started">Get started</Link>
</Button>

View file

@ -3,6 +3,7 @@
import React, { useState, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { Button } from "@katanemo/ui";
import Link from "next/link";
const carouselData = [
{
@ -12,6 +13,7 @@ const carouselData = [
description:
"Building AI agents is hard enough (iterate on prompts and evaluate LLMs, etc), the plumbing work shouldn't add to that complexity. Plano takes care of the critical plumbing work like routing and orchestration to agents that slows you down and locks you into rigid frameworks, freeing developers to innovate on what truly matters.",
image: "/LaunchFaster.svg",
link: "https://docs.plano.katanemo.com/getting-started/installation",
},
{
id: 2,
@ -20,6 +22,7 @@ const carouselData = [
description:
"Build with multiple LLMs or model versions with a single unified API. Plano centralizes access controls, offers resiliency for traffic to 100+ LLMs -- all without you having to write a single line of code.",
image: "/BuildWithChoice.svg",
link: "https://docs.plano.katanemo.com/getting-started/installation",
},
{
id: 3,
@ -28,6 +31,7 @@ const carouselData = [
description:
"Knowing when agents fail or delight users is a critical signal that feeds into a reinforcement learning and optimization cycle. Plano makes this trivial by sampling hyper-rich information traces from live production agentic interactions so that you can improve agent performance faster.",
image: "/Telemetry.svg",
link: "https://docs.plano.katanemo.com/getting-started/installation",
},
{
id: 4,
@ -36,6 +40,7 @@ const carouselData = [
description:
"Plano comes built-in with a state-of-the-art guardrail model you can use for things like jailbreak detection. But you can easily extend those capabilities via plano's agent filter chain to apply custom policy checks in a centralized way and keep users engaged on topics relevant to your requirements.",
image: "/ShipConfidently.svg",
link: "https://docs.plano.katanemo.com/getting-started/installation",
},
{
id: 5,
@ -44,6 +49,7 @@ const carouselData = [
description:
"Plano's sidecar deployment model avoids library-based abstractions - operating as a protocol-native data plane that integrates seamlessly with your existing agents via agentic APIs (like v1/responses). This decouples your core agent logic from plumbing concerns - run it alongside any framework without code changes, vendor lock-in, or performance overhead.",
image: "/Contextual.svg",
link: "https://docs.plano.katanemo.com/getting-started/installation",
},
];
@ -143,8 +149,8 @@ export function IdeaToAgentSection() {
</p>
</div>
<Button className="mt-6 sm:mt-8 w-full sm:w-auto">
Learn more
<Button asChild className="mt-6 sm:mt-8 w-full sm:w-auto">
<Link href={carouselData[currentSlide].link}>Learn more</Link>
</Button>
</div>
</div>

View file

@ -5,9 +5,9 @@ export function IntroSection() {
return (
<section className="relative bg-[#1a1a1a] text-white py-20 px-6 lg:px-[102px]">
<div className="max-w-324 mx-auto">
<div className="flex flex-col lg:flex-row gap-12 items-center">
<div className="flex flex-col lg:flex-row gap-12">
{/* Left Content */}
<div className="flex-1">
<div className="flex-1 mt-2">
{/* Heading */}
<p className="font-mono font-bold text-primary-light text-xl tracking-[1.92px]! mb-4 leading-[1.102]">
WHY PLANO?

View file

@ -26,7 +26,7 @@ const customerLogos = [
export function LogoCloud() {
return (
<section className="relative py-6 sm:py-8 px-4 sm:px-6 lg:px-8">
<section className="relative py-6 sm:py-8 px-4 sm:px-6 lg:px-8 bg-transparent">
<div className="max-w-[81rem] mx-auto">
<div className="grid grid-cols-2 md:grid-cols-3 lg:flex lg:flex-row lg:justify-center lg:items-center gap-4 sm:gap-6 md:gap-8 lg:gap-0 place-items-center">
{customerLogos.map((logo, index) => {

View file

@ -1,203 +1,200 @@
"use client";
import React, { useEffect, useState } from "react";
import React, { useId } from "react";
import { motion } from "framer-motion";
interface Node {
id: string;
x: number;
y: number;
size: number;
delay: number;
}
interface Connection {
from: string;
to: string;
}
interface Particle {
id: string;
connectionIndex: number;
progress: number;
}
// 4 separate groups positioned to the right of the heading text, aligned with the text vertically
const nodes: Node[] = [
// Group 1
{ id: "1", x: 20, y: 35, size: 18, delay: 0 },
{ id: "2", x: 70, y: 42, size: 12, delay: 0.8 },
{ id: "3", x: 76, y: 38, size: 16, delay: 1.6 },
// // Group 2
// { id: "4", x: 80, y: 30, size: 18, delay: 0.4 },
// { id: "5", x: 87, y: 36, size: 12, delay: 1.2 },
// { id: "6", x: 92, y: 33, size: 16, delay: 2.0 },
// Group 3
{ id: "7", x: 62, y: 48, size: 10, delay: 0.6 },
{ id: "8", x: 65, y: 52, size: 18, delay: 1.4 },
{ id: "9", x: 75, y: 48, size: 14, delay: 0.6 },
// Define the grid of squares with their positions and colors
const squares = [
// Column 1 (x=3)
{ x: 3, y: 3, color: "#B0B7FF", col: 0, row: 0 },
{ x: 3, y: 6, color: "#B0B7FF", col: 0, row: 1 },
{ x: 3, y: 9, color: "#B0B7FF", col: 0, row: 2 },
{ x: 3, y: 12, color: "#ABB2FA", col: 0, row: 3 },
{ x: 3, y: 15, color: "#ABB2FA", col: 0, row: 4 },
{ x: 3, y: 18, color: "#ABB2FA", col: 0, row: 5 },
{ x: 3, y: 21, color: "#969FF4", col: 0, row: 6 },
// Column 2 (x=6)
{ x: 6, y: 3, color: "#B0B7FF", col: 1, row: 0 },
{ x: 6, y: 6, color: "#B0B7FF", col: 1, row: 1 },
{ x: 6, y: 9, color: "#ABB2FA", col: 1, row: 2 },
{ x: 6, y: 12, color: "#ABB2FA", col: 1, row: 3 },
{ x: 6, y: 15, color: "#ABB2FA", col: 1, row: 4 },
{ x: 6, y: 18, color: "#969FF4", col: 1, row: 5 },
{ x: 6, y: 21, color: "#969FF4", col: 1, row: 6 },
// Column 3 (x=9)
{ x: 9, y: 3, color: "#B0B7FF", col: 2, row: 0 },
{ x: 9, y: 6, color: "#ABB2FA", col: 2, row: 1 },
{ x: 9, y: 9, color: "#ABB2FA", col: 2, row: 2 },
{ x: 9, y: 12, color: "#ABB2FA", col: 2, row: 3 },
{ x: 9, y: 15, color: "#969FF4", col: 2, row: 4 },
{ x: 9, y: 18, color: "#969FF4", col: 2, row: 5 },
{ x: 9, y: 21, color: "#969FF4", col: 2, row: 6 },
// Column 4 (x=12)
{ x: 12, y: 3, color: "#ABB2FA", col: 3, row: 0 },
{ x: 12, y: 6, color: "#ABB2FA", col: 3, row: 1 },
{ x: 12, y: 9, color: "#ABB2FA", col: 3, row: 2 },
{ x: 12, y: 12, color: "#969FF4", col: 3, row: 3 },
{ x: 12, y: 15, color: "#969FF4", col: 3, row: 4 },
{ x: 12, y: 18, color: "#969FF4", col: 3, row: 5 },
{ x: 12, y: 21, color: "#969FF4", col: 3, row: 6 },
// Column 5 (x=15)
{ x: 15, y: 3, color: "#ABB2FA", col: 4, row: 0 },
{ x: 15, y: 6, color: "#ABB2FA", col: 4, row: 1 },
{ x: 15, y: 9, color: "#969FF4", col: 4, row: 2 },
{ x: 15, y: 12, color: "#969FF4", col: 4, row: 3 },
{ x: 15, y: 15, color: "#969FF4", col: 4, row: 4 },
{ x: 15, y: 18, color: "#969FF4", col: 4, row: 5 },
{ x: 15, y: 21, color: "#969FF4", col: 4, row: 6 },
// Column 6 (x=18)
{ x: 18, y: 3, color: "#ABB2FA", col: 5, row: 0 },
{ x: 18, y: 6, color: "#969FF4", col: 5, row: 1 },
{ x: 18, y: 9, color: "#969FF4", col: 5, row: 2 },
{ x: 18, y: 12, color: "#969FF4", col: 5, row: 3 },
{ x: 18, y: 15, color: "#969FF4", col: 5, row: 4 },
{ x: 18, y: 18, color: "#969FF4", col: 5, row: 5 },
{ x: 18, y: 21, color: "#969FF4", col: 5, row: 6 },
// Column 7 (x=21)
{ x: 21, y: 3, color: "#969FF4", col: 6, row: 0 },
{ x: 21, y: 6, color: "#969FF4", col: 6, row: 1 },
{ x: 21, y: 9, color: "#969FF4", col: 6, row: 2 },
{ x: 21, y: 12, color: "#969FF4", col: 6, row: 3 },
{ x: 21, y: 15, color: "#969FF4", col: 6, row: 4 },
{ x: 21, y: 18, color: "#969FF4", col: 6, row: 5 },
{ x: 21, y: 21, color: "#969FF4", col: 6, row: 6 },
];
const connections: Connection[] = [
// Group 1 connections
{ from: "1", to: "2" },
{ from: "2", to: "3" },
interface NetworkAnimationProps {
className?: string;
}
// // Group 2 connections
// { from: "4", to: "5" },
// { from: "5", to: "6" },
// Deterministic seeded random number generator for consistent SSR/client values
function seededRandom(seed: number): number {
const x = Math.sin(seed) * 10000;
return x - Math.floor(x);
}
// Group 3 connections
{ from: "7", to: "8" },
{ from: "8", to: "9" },
];
// Round to fixed precision to avoid floating-point precision differences
function roundToPrecision(value: number, precision: number = 10): number {
return Math.round(value * Math.pow(10, precision)) / Math.pow(10, precision);
}
export function NetworkAnimation() {
const [particles, setParticles] = useState<Particle[]>([]);
// Create and animate particles along connections - much slower
useEffect(() => {
const createParticle = () => {
const connectionIndex = Math.floor(Math.random() * connections.length);
const particle: Particle = {
id: `particle-${Date.now()}-${Math.random()}`,
connectionIndex,
progress: 0,
};
setParticles((prev) => [...prev, particle]);
// Remove particle after animation completes
setTimeout(() => {
setParticles((prev) => prev.filter((p) => p.id !== particle.id));
}, 5000); // Slower duration
};
// Create particles at slower intervals
const interval = setInterval(createParticle, 2500);
return () => clearInterval(interval);
}, []);
// Animate particles - slower movement
useEffect(() => {
const interval = setInterval(() => {
setParticles((prev) =>
prev
.map((p) => ({ ...p, progress: p.progress + 0.008 })) // Much slower
.filter((p) => p.progress <= 1),
);
}, 50);
return () => clearInterval(interval);
}, []);
// Generate deterministic random values based on index
function getDeterministicValues(index: number) {
const seed1 = index * 0.1;
const seed2 = index * 0.2;
const seed3 = index * 0.3;
const seed4 = index * 0.4;
const seed5 = index * 0.5;
const seed6 = index * 0.6;
return {
duration: roundToPrecision(3 + seededRandom(seed1) * 3, 10), // 3-6 seconds
peakOpacity: roundToPrecision(0.7 + seededRandom(seed2) * 0.3, 10),
baseOpacity: roundToPrecision(0.3 + seededRandom(seed3) * 0.2, 10),
midOpacity: roundToPrecision(0.5 + seededRandom(seed4) * 0.2, 10),
baseBrightness: roundToPrecision(0.85 + seededRandom(seed5) * 0.15, 10),
peakBrightness: roundToPrecision(1.0 + seededRandom(seed6) * 0.2, 10),
};
}
export function NetworkAnimation({ className }: NetworkAnimationProps) {
// Generate unique IDs for gradient and mask to avoid conflicts when multiple instances exist
const gradientId = useId().replace(/:/g, '-');
const maskId = useId().replace(/:/g, '-');
return (
<div className="absolute inset-0 pointer-events-none z-0 opacity-8 rotate-20 translate-x-40 -translate-y-40 scale-75 lg:scale-100 xl:scale-125 2xl:scale-150 [@media(min-width:1800px)]:scale-[1.60]">
<svg
className="absolute inset-0 w-full h-full rotate-10"
preserveAspectRatio="xMidYMid slice"
viewBox="790 -90 1020 840"
style={{ overflow: "visible" }}
<div className="absolute inset-0 pointer-events-none opacity-100">
<motion.div
className={`absolute
top-[9%] right-[-3%] w-[380px] h-[380px] ${className || ""}`}
initial={{
rotate: 9, // Start at the same rotation as animation to prevent flicker
}}
animate={{
rotate: [9, 10, 9], // Slight breathing rotation
}}
transition={{
duration: 8,
repeat: Infinity,
ease: "easeInOut",
}}
>
<defs>
{/* Simple glow filter */}
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" result="coloredBlur" />
<feMerge>
<feMergeNode in="coloredBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
{/* Render connections - simple lines with lower opacity */}
{connections.map((conn, index) => {
const fromNode = nodes.find((n) => n.id === conn.from);
const toNode = nodes.find((n) => n.id === conn.to);
if (!fromNode || !toNode) return null;
const x1 = (fromNode.x / 100) * 1920;
const y1 = (fromNode.y / 100) * 800;
const x2 = (toNode.x / 100) * 1920;
const y2 = (toNode.y / 100) * 800;
return (
<line
key={`line-${conn.from}-${conn.to}`}
x1={x1}
y1={y1}
x2={x2}
y2={y2}
stroke="#8b91e8"
strokeWidth="1.5"
opacity={1}
/>
);
})}
{/* Render data particles with lower opacity */}
{particles.map((particle) => {
const conn = connections[particle.connectionIndex];
const fromNode = nodes.find((n) => n.id === conn.from);
const toNode = nodes.find((n) => n.id === conn.to);
if (!fromNode || !toNode) return null;
const x =
((fromNode.x + (toNode.x - fromNode.x) * particle.progress) / 100) *
1920;
const y =
((fromNode.y + (toNode.y - fromNode.y) * particle.progress) / 100) *
800;
return (
<motion.circle
key={particle.id}
cx={x}
cy={y}
r={4}
fill="#b9bfff"
initial={{ opacity: 0 }}
animate={{
opacity: [0, 0.4, 0.4, 0],
}}
transition={{
duration: 5,
times: [0, 0.2, 0.8, 1],
ease: "linear",
}}
/>
);
})}
{/* Render nodes with subtle floating animation */}
{nodes.map((node) => {
const size = node.size;
const baseX = (node.x / 100) * 1920;
const baseY = (node.y / 100) * 800;
return (
<motion.circle
key={node.id}
cx={baseX}
cy={baseY}
r={size}
fill="#8b91e8"
animate={{
cx: [baseX - 2, baseX + 2, baseX - 2],
cy: [baseY - 2, baseY + 2, baseY - 2],
}}
transition={{
duration: 10 + node.delay,
delay: node.delay,
repeat: Infinity,
ease: "easeInOut",
}}
/>
);
})}
</svg>
<svg
width="100%"
height="100%"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
{/* Gradient mask: transparent at bottom, opaque at top */}
<linearGradient id={gradientId} x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="white" stopOpacity="1" />
<stop offset="50%" stopColor="white" stopOpacity="0.5" />
<stop offset="100%" stopColor="white" stopOpacity="0" />
</linearGradient>
<mask id={maskId}>
<rect width="26" height="26" fill={`url(#${gradientId})`} />
</mask>
</defs>
<g mask={`url(#${maskId})`}>
{/* Outer border */}
<rect width="26" height="26" fill="#7780D9" />
{/* Inner background */}
<rect x="2" y="2" width="22" height="22" fill="#B9BFFF" />
{/* Animated squares with wave effect */}
{squares.map((square, index) => {
// Use deterministic values based on index for SSR/client consistency
const { duration, peakOpacity, baseOpacity, midOpacity, baseBrightness, peakBrightness } =
getDeterministicValues(index);
return (
<motion.path
key={`square-${index}`}
d={`M${square.x} ${square.y}H${square.x + 2}V${square.y + 2}H${square.x}V${square.y}Z`}
fill={square.color}
initial={{
opacity: roundToPrecision(baseOpacity, 10),
filter: `brightness(${roundToPrecision(baseBrightness, 10)})`,
}}
animate={{
opacity: [
roundToPrecision(baseOpacity, 10),
roundToPrecision(midOpacity, 10),
roundToPrecision(peakOpacity, 10),
roundToPrecision(midOpacity, 10),
roundToPrecision(baseOpacity, 10),
],
filter: [
`brightness(${roundToPrecision(baseBrightness, 10)})`,
`brightness(${roundToPrecision((baseBrightness + peakBrightness) / 2, 10)})`,
`brightness(${roundToPrecision(peakBrightness, 10)})`,
`brightness(${roundToPrecision((baseBrightness + peakBrightness) / 2, 10)})`,
`brightness(${roundToPrecision(baseBrightness, 10)})`,
],
}}
transition={{
duration: roundToPrecision(duration, 10),
delay: 0, // No delay - instant start
repeat: Infinity,
ease: "easeInOut",
repeatDelay: 0, // No pause between cycles
}}
/>
);
})}
</g>
</svg>
</motion.div>
</div>
);
}

View file

@ -1,5 +1,6 @@
import React from "react";
import { Button } from "@katanemo/ui";
import Link from "next/link";
interface UnlockPotentialSectionProps {
variant?: "transparent" | "black";
@ -31,8 +32,12 @@ export function UnlockPotentialSection({
</h2>
<div className="flex flex-col sm:flex-row gap-5">
<Button>Deploy today</Button>
<Button variant="secondaryDark">Documentation</Button>
<Button asChild>
<Link href="https://docs.plano.katanemo.com">Deploy today</Link>
</Button>
<Button variant="secondaryDark" asChild>
<Link href="https://docs.plano.katanemo.com">Documentation</Link>
</Button>
</div>
</div>
</div>

View file

@ -20,6 +20,7 @@ import {
DialogClose,
} from "@katanemo/ui";
import { motion, AnimatePresence } from "framer-motion";
import Link from "next/link";
interface UseCase {
id: number;
@ -113,7 +114,9 @@ export function UseCasesSection() {
<h2 className="font-sans font-normal text-2xl sm:text-3xl lg:text-4xl tracking-[-2px] sm:tracking-[-2.88px]! text-black leading-[1.03]">
What's possible with Plano
</h2>
<Button className="hidden lg:block">Start building</Button>
<Button asChild className="hidden lg:block">
<Link href="https://docs.plano.katanemo.com/getting-started/installation">Start building</Link>
</Button>
</div>
</div>
@ -152,7 +155,9 @@ export function UseCasesSection() {
{/* Start building button - Mobile only, appears last */}
<div className="lg:hidden mt-8">
<Button className="w-full">Start building</Button>
<Button asChild className="w-full">
<Link href="https://docs.plano.katanemo.com/getting-started/installation">Start building</Link>
</Button>
</div>
</div>
@ -278,7 +283,8 @@ export function UseCasesSection() {
<span>Ready to get started?</span>
</div>
<div className="flex flex-col sm:flex-row gap-3 w-full sm:w-auto order-1">
<Button className="w-full sm:w-auto">
<Button asChild className="w-full sm:w-auto">
<Link href="https://docs.plano.katanemo.com/getting-started/installation">Start building</Link>
Start building
<ArrowRightIcon className="w-4 h-4" />
</Button>

View file

@ -0,0 +1,65 @@
import React from "react";
import Image from "next/image";
export function ResearchBenchmarks() {
return (
<section className="relative py-12 sm:py-16 lg:py-20 px-4 sm:px-6 lg:px-[102px] bg-[#1a1a1a] border-b-2 border-white/10">
<div className="max-w-[81rem] mx-auto">
{/* Section Header */}
<div className="mb-8 sm:mb-12 lg:mb-6">
{/* BENCHMARKS Label */}
<div className="mb-4 sm:mb-2">
<div className="font-mono font-bold text-[#9797ea] text-sm sm:text-base lg:text-xl tracking-[1.44px] sm:tracking-[1.92px]! leading-[1.502]">
BENCHMARKS
</div>
</div>
{/* Title */}
<h2 className="text-4xl sm:text-4xl md:text-5xl lg:text-4xl font-medium leading-tight tracking-[-0.06em]! text-white">
<span className="font-sans">Production excellence, outperforming frontier LLMs</span>
</h2>
</div>
{/* Benchmarks Image */}
{/* Mobile: Full-width scrollable container that extends to viewport edges */}
<div
className="mt-5 lg:hidden relative left-1/2 right-1/2 -ml-[50vw] -mr-[50vw] w-screen overflow-x-auto overflow-y-visible"
style={{
scrollbarWidth: "none",
msOverflowStyle: "none",
WebkitOverflowScrolling: "touch",
}}
>
<style jsx>{`
.benchmarks-scroll-container::-webkit-scrollbar {
display: none;
}
`}</style>
<div className="benchmarks-scroll-container inline-block pl-4 sm:pl-6">
<Image
src="/Benchmarks.svg"
alt="Benchmarks"
width={1200}
height={600}
className="h-auto"
style={{ width: "1200px", maxWidth: "none", display: "block" }}
priority
/>
</div>
</div>
{/* Desktop: Normal display */}
<div className="hidden lg:block w-full">
<Image
src="/Benchmarks.svg"
alt="Benchmarks"
width={1200}
height={600}
className="w-full h-auto"
priority
/>
</div>
</div>
</section>
);
}

View file

@ -0,0 +1,39 @@
import React from "react";
import { Button } from "@katanemo/ui";
import Link from "next/link";
export function ResearchCTA() {
return (
<section className="relative pt-16 sm:pt-20 lg:pt-24 pb-12 sm:pb-16 lg:pb-20 px-4 sm:px-6 lg:px-[102px] bg-[#1a1a1a]">
<div className="max-w-[81rem] mx-auto relative z-10">
<div className="max-w-4xl">
{/* Main Heading */}
<h1 className="text-4xl sm:text-4xl md:text-5xl lg:text-5xl font-medium leading-tight tracking-[-0.06em]! text-white -ml-1 mb-3 mt-4">
<span className="font-sans">Meet Plano-Orchestrator. Our latest models.</span>
</h1>
</div>
{/* Description with CTA Buttons */}
<div className="max-w-2xl">
{/* text-base sm:text-lg md:text-xl lg:text-2xl font-sans font-[400] tracking-[-1.2px] sm:tracking-[-1.82px]! text-black max-w-70 sm:max-w-2xl mb-6 */}
<p className="leading-relaxed sm:text-lg md:text-xl lg:text-2xl font-sans font-normal tracking-[-1.0px] sm:tracking-[-1.22px]! text-white/90 mb-6">
Plano-Orchestrator is a family of state-of-the-art routing and orchestration models
that decides which agent(s) or LLM(s) should handle each request, and in what sequence.
Built for multi-agent orchestration systems, Plano-Orchestrator excels at analyzing
user intent and conversation context to make precise routing and orchestration decisions.
</p>
{/* CTA Buttons */}
<div className="flex flex-col sm:flex-row items-stretch sm:items-start gap-3 sm:gap-4">
<Button asChild className="w-full sm:w-auto">
<Link href="https://huggingface.co/katanemo">Download Plano models</Link>
</Button>
<Button variant="secondary" asChild className="w-full sm:w-auto">
<Link href="https://docs.plano.katanemo.com">Get Started with Plano</Link>
</Button>
</div>
</div>
</div>
</section>
);
}

View file

@ -0,0 +1,152 @@
"use client";
import React from "react";
import { motion } from "framer-motion";
import { MessagesSquare, GitFork, Route, RefreshCw } from "lucide-react";
interface Capability {
id: number;
title: string;
description: string;
}
const capabilitiesData: Capability[] = [
{
id: 1,
title: "Multi-turn Understanding",
description:
"Makes routing decisions based on full conversation history, maintaining contextual awareness across extended dialogues with evolving user needs.",
},
{
id: 2,
title: "Multi-Intent Detection",
description:
"Identifies when a single user message requires multiple agents simultaneously, enabling parallel/sequential routing to fulfill complex requests",
},
{
id: 3,
title: "Content-Dependency Routing",
description:
"Correctly interprets ambiguous or referential messages by leveraging prior conversation context for accurate routing decisions.",
},
{
id: 4,
title: "Conversational-Flow Handling",
description:
"Understands diverse interaction patterns including follow-ups, clarifications, confirmations, and corrections within ongoing conversations.",
},
];
export function ResearchCapabilities() {
return (
<section className="relative py-12 sm:py-16 lg:py-20 px-4 sm:px-6 lg:px-[102px] bg-[#1a1a1a]">
<div className="max-w-[81rem] mx-auto">
{/* Section Header */}
<div className="mb-8 sm:mb-12 lg:mb-10">
{/* PLANO-4B CAPABILITIES Label */}
<div className="mb-2 sm:mb-1">
<div className="font-mono font-bold text-[#9797ea] text-sm sm:text-base lg:text-xl tracking-[1.44px] sm:tracking-[1.92px]! leading-[1.502]">
PLANO-4B CAPABILITIES
</div>
</div>
{/* Title */}
<h2 className="text-4xl sm:text-4xl md:text-5xl lg:text-4xl font-medium leading-tight tracking-[-0.06em]! text-white mb-4">
<span className="font-sans">Accurately route with confidence with no compromise</span>
</h2>
<p className="font-mono text-white/90 w-[75%] text-sm sm:text-base tracking-[-0.8px] sm:tracking-[-1.2px]! leading-relaxed">
Designed for real-world deployments, it delivers strong performance across general
conversations, coding tasks, and long-context multi-turn conversations, while remaining
efficient enough for low-latency production environments.
</p>
</div>
{/* Mobile: Icon card above title/description, stacked vertically */}
<div className="lg:hidden grid grid-cols-1 gap-8">
{capabilitiesData.map((capability) => {
// Map each capability to its icon
const iconMap: Record<number, React.ComponentType<{ className?: string }>> = {
1: MessagesSquare, // Multi-turn Understanding
2: GitFork, // Multi-Intent Detection
3: Route, // Content-Dependency Routing
4: RefreshCw, // Conversational-Flow Handling
};
const Icon = iconMap[capability.id];
return (
<div key={capability.id} className="flex flex-col">
{/* Icon Card */}
<motion.div
whileHover={{ y: -4 }}
transition={{ duration: 0.2 }}
className="bg-gradient-to-b from-[rgba(177,184,255,0.16)] to-[rgba(17,28,132,0.035)] border-2 border-[rgba(171,178,250,0.27)] rounded-md p-6 h-40 flex items-center justify-center mb-4"
>
{Icon && (
<Icon className="w-24 h-24 text-[#9797ea]" />
)}
</motion.div>
{/* Title */}
<h3 className="font-sans font-medium text-white text-xl tracking-[-1.2px]! leading-[1.102] mb-3">
{capability.title}
</h3>
{/* Description */}
<p className="font-mono text-white/90 text-base tracking-[-0.8px]! leading-relaxed">
{capability.description}
</p>
</div>
);
})}
</div>
{/* Desktop: Icon cards separate from titles/descriptions */}
<div className="hidden lg:grid lg:grid-cols-4 gap-6 mb-6">
{capabilitiesData.map((capability) => {
// Map each capability to its icon
const iconMap: Record<number, React.ComponentType<{ className?: string }>> = {
1: MessagesSquare, // Multi-turn Understanding
2: GitFork, // Multi-Intent Detection
3: Route, // Content-Dependency Routing
4: RefreshCw, // Conversational-Flow Handling
};
const Icon = iconMap[capability.id];
return (
<motion.div
key={capability.id}
whileHover={{ y: -4 }}
transition={{ duration: 0.2 }}
className="bg-gradient-to-b from-[rgba(177,184,255,0.16)] to-[rgba(17,28,132,0.035)] border-2 border-[rgba(171,178,250,0.27)] rounded-md p-6 h-52 flex items-center justify-center"
>
{Icon && (
<Icon className="w-24 h-24 text-[#9797ea]" />
)}
</motion.div>
);
})}
</div>
{/* Desktop: Titles and Descriptions Below Boxes */}
<div className="hidden lg:grid lg:grid-cols-4 gap-6">
{capabilitiesData.map((capability) => (
<div key={capability.id}>
{/* Title */}
<h3 className="font-sans font-medium text-white text-2xl tracking-[-1.2px]! leading-[1.102] mb-4">
{capability.title}
</h3>
{/* Description */}
<p className="font-mono text-white/90 text-base tracking-[-1.2px]! leading-relaxed">
{capability.description}
</p>
</div>
))}
</div>
</div>
</section>
);
}

View file

@ -0,0 +1,111 @@
"use client";
import React from "react";
import Image from "next/image";
import { Check } from "lucide-react";
import { motion } from "framer-motion";
interface ModelFeature {
text: string;
}
interface Model {
id: number;
name: string;
logo: string;
features: ModelFeature[];
}
const modelsData: Model[] = [
{
id: 1,
name: "Plano-4B",
logo: "/Plano4B-Logo.svg",
features: [
{ text: "Optimized for production routing with sub-100ms latency" },
{ text: "84-87% accuracy on long-context scenarios" },
{ text: "Cost-effective model selection at scale" },
{ text: "Seamless agent orchestration capabilities" },
{ text: "Frontier-level performance at fraction of cost" },
],
},
{
id: 2,
name: "Plano-30B-A3B",
logo: "/Plano30B-Logo.svg",
features: [
{ text: "Advanced routing intelligence for complex workflows" },
{ text: "Enhanced context understanding and preservation" },
{ text: "Superior accuracy for multi-agent coordination" },
{ text: "Enterprise-grade performance and reliability" },
{ text: "Scalable architecture for high-throughput systems" },
],
},
];
export function ResearchFamily() {
return (
<section className="relative py-16 sm:py-20 lg:py-24 px-4 sm:px-6 lg:px-[102px] bg-white">
<div className="max-w-[81rem] mx-auto">
{/* Section Header */}
<div className="mb-8 sm:mb-12 lg:mb-10">
{/* PLANO FAMILY Label */}
<div className="mb-4 sm:mb-2">
<div className="font-mono font-bold text-[#2A3178] text-sm sm:text-base lg:text-xl tracking-[1.44px] sm:tracking-[1.92px]! leading-[1.502]">
PLANO FAMILY
</div>
</div>
{/* Title */}
<h2 className="text-4xl sm:text-4xl md:text-5xl lg:text-4xl font-medium leading-tight tracking-[-0.06em]! text-black -ml-1">
<span className="font-sans">Plano Models</span>
</h2>
</div>
{/* 2 Card Grid - Side by Side */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
{modelsData.map((model) => (
<motion.div
key={model.id}
whileHover={{ y: -4 }}
transition={{ duration: 0.2 }}
className="bg-gradient-to-b from-[rgba(177,184,255,0.16)] to-[rgba(17,28,132,0.035)] border-2 border-[rgba(171,178,250,0.27)] rounded-md p-6 sm:p-6 lg:p-6 h-72"
>
{/* Empty box - content is below */}
</motion.div>
))}
</div>
{/* Titles and Descriptions Below Boxes */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{modelsData.map((model) => (
<div key={model.id}>
{/* Logo */}
<div className="mb-6">
<Image
src={model.logo}
alt={model.name}
width={200}
height={60}
className="h-12 w-auto"
/>
</div>
{/* Features List */}
<div>
{model.features.map((feature, index) => (
<div key={index} className="flex items-start gap-3 mb-4">
<Check className="w-5 h-5 text-[var(--primary)] flex-shrink-0 mt-0.5" />
<p className="font-mono text-black text-sm sm:text-base tracking-[-0.8px] sm:tracking-[-1.2px]! leading-relaxed">
{feature.text}
</p>
</div>
))}
</div>
</div>
))}
</div>
</div>
</section>
);
}

View file

@ -0,0 +1,49 @@
import React from "react";
interface ResearchItem {
title: string;
description: string;
}
const researchItems: ResearchItem[] = [
{
title: "Model Routing",
description:
"Great agent UX starts with using the best model for a task — fast and cheap when it can be, smarter when it needs to be — and our routing research gives developers the controls to do exactly that. Our policy-based router captures your evals and preferences, while our performance-based router learns from real traffic over time, so you can evolve model choices without retraining.",
},
{
title: "Governance & Learning",
description:
"Building an agent is easy — knowing what it does in production and how to improve it is very hard. Our research focuses on making agent behavior observable and governable: studying how agents respond to real and adversarial traffic, policy changes, and turning signals into learning loops that make agents safer and more effective over time.",
},
{
title: "Better Performance",
description:
"Better system performance comes from directing traffic to the right agents for each task or workflow. We build compact orchestration models that manage traffic between agents — ensuring clean handoffs, preserved context, and reliable multi-agent collaboration across distributed systems.",
},
];
export function ResearchGrid() {
return (
<section className="relative py-12 sm:py-16 lg:py-20 px-4 sm:px-6 lg:px-[102px] bg-white">
<div className="max-w-[81rem] mx-auto">
{/* 3 Column Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8 lg:gap-12">
{researchItems.map((item, index) => (
<div key={index} className="flex flex-col">
{/* Title */}
<h3 className="font-sans font-medium text-2xl sm:text-3xl lg:text-3xl tracking-[-1.5px] sm:tracking-[-2px]! text-black leading-[1.1] mb-2 sm:mb-4">
{item.title}
</h3>
{/* Description */}
<p className="font-mono text-black text-sm sm:text-base lg:text-lg leading-relaxed tracking-[-0.8px] sm:tracking-[-1.2px]!">
{item.description}
</p>
</div>
))}
</div>
</div>
</section>
);
}

View file

@ -0,0 +1,59 @@
import React from "react";
import { NetworkAnimation } from "../NetworkAnimation";
import { Button } from "@katanemo/ui";
import Link from "next/link";
export function ResearchHero() {
return (
<section className="relative pt-8 sm:pt-12 lg:pt-16 pb-12 sm:pb-16 lg:pb-20 px-4 sm:px-6 lg:px-[102px] overflow-hidden">
<div className="max-w-[81rem] mx-auto relative">
<div className="hidden lg:block absolute inset-0 pointer-events-none">
<NetworkAnimation className="!w-[500px] !h-[500px] xl:!w-[600px] xl:!h-[600px] 2xl:!w-[570px] 2xl:!h-[570px]" />
</div>
<div className="lg:hidden absolute inset-0 pointer-events-none">
<NetworkAnimation className="!w-[300px] !h-[300px] left-77! -top-2! opacity-90! " />
</div>
<div className="max-w-3xl relative z-10">
{/* Badge */}
<div className="mb-4 sm:mb-6">
<div className="inline-flex flex-wrap items-center gap-1.5 sm:gap-2 px-3 sm:px-4 py-1 rounded-full bg-[rgba(185,191,255,0.4)] border border-[var(--secondary)] shadow backdrop-blur">
<span className="text-xs sm:text-sm font-medium text-black/65">
New!
</span>
<span className="text-xs sm:text-sm font-medium text-black hidden sm:inline">
</span>
<span className="text-xs sm:text-sm font-[600] tracking-[-0.6px]! text-black leading-tight">
<span className="hidden sm:inline">
Plano-4B - The state-of-the-art agent routing and orchestration LLM
</span>
<span className="sm:hidden">Unified /v1/responses API</span>
</span>
</div>
</div>
{/* Main Heading */}
<h1 className="text-4xl sm:text-4xl md:text-5xl lg:text-7xl font-medium leading-tight tracking-tighter text-black -ml-1 mb-3 mt-4">
<span className="font-sans">Research</span>
</h1>
</div>
{/* Description */}
<div className="max-w-70 sm:max-w-2xl relative z-10">
<p className="text-base sm:text-lg md:text-xl lg:text-2xl font-sans font-normal tracking-[-1.0px] sm:tracking-[-1.22px]! text-black">
Our open source applied research focuses on how to deliver agents
safely, efficiently, and with predictable real-world performance
critical for any AI application, but sits outside any products core
business logic.
</p>
</div>
<div className="flex flex-col sm:flex-row items-stretch sm:items-start gap-3 sm:gap-4 mt-6 sm:mt-8 relative z-10">
<Button asChild className="w-full sm:w-auto">
<Link href="https://huggingface.co/katanemo">Available on Hugging Face</Link>
</Button>
</div>
</div>
</section>
);
}

View file

@ -0,0 +1,50 @@
import React from "react";
import Image from "next/image";
export function ResearchTimeline() {
return (
<section className="relative py-12 sm:py-16 lg:py-16 px-4 sm:px-6 lg:px-[102px] bg-white border-b border-gray-200">
<div className="max-w-[81rem] mx-auto">
{/* Timeline Image */}
{/* Mobile: Full-width scrollable container that extends to viewport edges */}
<div
className="mt-5 lg:hidden relative left-1/2 right-1/2 -ml-[50vw] -mr-[50vw] w-screen overflow-x-auto overflow-y-visible"
style={{
scrollbarWidth: "none",
msOverflowStyle: "none",
WebkitOverflowScrolling: "touch",
}}
>
<style jsx>{`
.timeline-scroll-container::-webkit-scrollbar {
display: none;
}
`}</style>
<div className="timeline-scroll-container inline-block pl-4 sm:pl-6">
<Image
src="/Timeline.svg"
alt="Research Timeline"
width={1200}
height={600}
className="h-auto"
style={{ width: "1200px", maxWidth: "none", display: "block" }}
priority
/>
</div>
</div>
{/* Desktop: Normal display */}
<div className="hidden lg:block w-full">
<Image
src="/Timeline.svg"
alt="Research Timeline"
width={1200}
height={600}
className="w-full h-auto"
priority
/>
</div>
</div>
</section>
);
}

View file

@ -0,0 +1,7 @@
export { ResearchHero } from "./ResearchHero";
export { ResearchGrid } from "./ResearchGrid";
export { ResearchTimeline } from "./ResearchTimeline";
export { ResearchCTA } from "./ResearchCTA";
export { ResearchCapabilities } from "./ResearchCapabilities";
export { ResearchBenchmarks } from "./ResearchBenchmarks";
export { ResearchFamily } from "./ResearchFamily";

56
package-lock.json generated
View file

@ -12,7 +12,7 @@
"packages/*"
],
"devDependencies": {
"turbo": "^2.0.0"
"turbo": "^2.6.3"
},
"engines": {
"node": ">=18.0.0"
@ -16061,27 +16061,27 @@
}
},
"node_modules/turbo": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo/-/turbo-2.6.1.tgz",
"integrity": "sha512-qBwXXuDT3rA53kbNafGbT5r++BrhRgx3sAo0cHoDAeG9g1ItTmUMgltz3Hy7Hazy1ODqNpR+C7QwqL6DYB52yA==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/turbo/-/turbo-2.6.3.tgz",
"integrity": "sha512-bf6YKUv11l5Xfcmg76PyWoy/e2vbkkxFNBGJSnfdSXQC33ZiUfutYh6IXidc5MhsnrFkWfdNNLyaRk+kHMLlwA==",
"dev": true,
"license": "MIT",
"bin": {
"turbo": "bin/turbo"
},
"optionalDependencies": {
"turbo-darwin-64": "2.6.1",
"turbo-darwin-arm64": "2.6.1",
"turbo-linux-64": "2.6.1",
"turbo-linux-arm64": "2.6.1",
"turbo-windows-64": "2.6.1",
"turbo-windows-arm64": "2.6.1"
"turbo-darwin-64": "2.6.3",
"turbo-darwin-arm64": "2.6.3",
"turbo-linux-64": "2.6.3",
"turbo-linux-arm64": "2.6.3",
"turbo-windows-64": "2.6.3",
"turbo-windows-arm64": "2.6.3"
}
},
"node_modules/turbo-darwin-64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.6.1.tgz",
"integrity": "sha512-Dm0HwhyZF4J0uLqkhUyCVJvKM9Rw7M03v3J9A7drHDQW0qAbIGBrUijQ8g4Q9Cciw/BXRRd8Uzkc3oue+qn+ZQ==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.6.3.tgz",
"integrity": "sha512-BlJJDc1CQ7SK5Y5qnl7AzpkvKSnpkfPmnA+HeU/sgny3oHZckPV2776ebO2M33CYDSor7+8HQwaodY++IINhYg==",
"cpu": [
"x64"
],
@ -16093,9 +16093,9 @@
]
},
"node_modules/turbo-darwin-arm64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.6.1.tgz",
"integrity": "sha512-U0PIPTPyxdLsrC3jN7jaJUwgzX5sVUBsKLO7+6AL+OASaa1NbT1pPdiZoTkblBAALLP76FM0LlnsVQOnmjYhyw==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.6.3.tgz",
"integrity": "sha512-MwVt7rBKiOK7zdYerenfCRTypefw4kZCue35IJga9CH1+S50+KTiCkT6LBqo0hHeoH2iKuI0ldTF2a0aB72z3w==",
"cpu": [
"arm64"
],
@ -16107,9 +16107,9 @@
]
},
"node_modules/turbo-linux-64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.6.1.tgz",
"integrity": "sha512-eM1uLWgzv89bxlK29qwQEr9xYWBhmO/EGiH22UGfq+uXr+QW1OvNKKMogSN65Ry8lElMH4LZh0aX2DEc7eC0Mw==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.6.3.tgz",
"integrity": "sha512-cqpcw+dXxbnPtNnzeeSyWprjmuFVpHJqKcs7Jym5oXlu/ZcovEASUIUZVN3OGEM6Y/OTyyw0z09tOHNt5yBAVg==",
"cpu": [
"x64"
],
@ -16121,9 +16121,9 @@
]
},
"node_modules/turbo-linux-arm64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.6.1.tgz",
"integrity": "sha512-MFFh7AxAQAycXKuZDrbeutfWM5Ep0CEZ9u7zs4Hn2FvOViTCzIfEhmuJou3/a5+q5VX1zTxQrKGy+4Lf5cdpsA==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.6.3.tgz",
"integrity": "sha512-MterpZQmjXyr4uM7zOgFSFL3oRdNKeflY7nsjxJb2TklsYqiu3Z9pQ4zRVFFH8n0mLGna7MbQMZuKoWqqHb45w==",
"cpu": [
"arm64"
],
@ -16135,9 +16135,9 @@
]
},
"node_modules/turbo-windows-64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.6.1.tgz",
"integrity": "sha512-buq7/VAN7KOjMYi4tSZT5m+jpqyhbRU2EUTTvp6V0Ii8dAkY2tAAjQN1q5q2ByflYWKecbQNTqxmVploE0LVwQ==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.6.3.tgz",
"integrity": "sha512-biDU70v9dLwnBdLf+daoDlNJVvqOOP8YEjqNipBHzgclbQlXbsi6Gqqelp5er81Qo3BiRgmTNx79oaZQTPb07Q==",
"cpu": [
"x64"
],
@ -16149,9 +16149,9 @@
]
},
"node_modules/turbo-windows-arm64": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.6.1.tgz",
"integrity": "sha512-7w+AD5vJp3R+FB0YOj1YJcNcOOvBior7bcHTodqp90S3x3bLgpr7tE6xOea1e8JkP7GK6ciKVUpQvV7psiwU5Q==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.6.3.tgz",
"integrity": "sha512-dDHVKpSeukah3VsI/xMEKeTnV9V9cjlpFSUs4bmsUiLu3Yv2ENlgVEZv65wxbeE0bh0jjpmElDT+P1KaCxArQQ==",
"cpu": [
"arm64"
],

View file

@ -15,11 +15,10 @@
"clean": "turbo run clean && rm -rf node_modules"
},
"devDependencies": {
"turbo": "^2.0.0"
"turbo": "^2.6.3"
},
"engines": {
"node": ">=18.0.0"
},
"packageManager": "npm@10.0.0"
}

View file

@ -7,6 +7,11 @@
@custom-variant dark (&:is(.dark *));
/* Custom breakpoint for extra large screens */
@theme {
--breakpoint-3xl: 1920px;
}
/* Font Face Declarations */
@font-face {
font-family: "IBM Plex Sans";

View file

@ -3,13 +3,17 @@ import Link from "next/link";
import Image from "next/image";
const footerLinks = {
company: [
{ label: "Product", href: "/product" },
{ label: "Use Cases", href: "/use-cases" },
product: [
{ label: "Research", href: "/research" },
{ label: "Blog", href: "/blog" },
{ label: "Plano LLMs", href: "/llms" },
{ label: "Documentation", href: "https://docs.plano.katanemo.com", external: true },
{ label: "Hugging Face", href: "https://huggingface.co/katanemo", external: true },
],
resources: [
{ label: "GitHub", href: "https://github.com/katanemo/arch", external: true },
{ label: "Discord", href: "https://discord.gg/pGZf2gcwEc", external: true },
{ label: "Get Started", href: "https://docs.plano.katanemo.com/getting-started/installation", external: true },
],
developerResources: [{ label: "Documentation", href: "/docs" }],
};
export function Footer() {
@ -23,9 +27,10 @@ export function Footer() {
<div className="grid grid-cols-1 lg:grid-cols-2 gap-20">
{/* Left Column - Tagline and Copyright */}
<div className="flex flex-col">
<p className="font-sans font-normal text-lg sm:text-xl lg:text-2xl text-black tracking-[-1.2px] sm:tracking-[-1.5px] lg:tracking-[-1.7px]! leading-7 mb-6 sm:mb-8">
Plano is the powerful, intelligent platform that empowers teams to
seamlessly build, automate, and scale agentic systems with ease.
<p className="font-sans font-normal text-lg sm:text-xl lg:text-2xl text-black tracking-[-1.2px] sm:tracking-[-1.5px] lg:tracking-[-1.7px]! leading-relaxed mb-6 sm:mb-8">
Plano is a powerful agent delivery infrastructure platform that is framework-friendly,
and empowers developers and teams to seamlessly build, deliver, and scale agentic
applications.
</p>
{/* Copyright */}
@ -38,16 +43,18 @@ export function Footer() {
{/* Right Column - Navigation Links */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-8">
{/* Company Links */}
{/* Product Links */}
<div>
<h3 className="font-sans font-normal text-xl sm:text-2xl lg:text-3xl text-black tracking-[-1.2px] sm:tracking-[-1.4px] lg:tracking-[-1.6px]! mb-4 sm:mb-6">
Company
Product
</h3>
<nav className="space-y-3 sm:space-y-4">
{footerLinks.company.map((link) => (
{footerLinks.product.map((link) => (
<Link
key={link.href}
href={link.href}
target={link.external ? "_blank" : undefined}
rel={link.external ? "noopener noreferrer" : undefined}
className="block font-sans font-normal text-sm sm:text-base lg:text-lg text-black tracking-[-0.8px] sm:tracking-[-0.9px] lg:tracking-[-1px]! hover:text-[var(--primary)] transition-colors"
>
{link.label}
@ -56,16 +63,18 @@ export function Footer() {
</nav>
</div>
{/* Developer Resources */}
{/* Resources Links */}
<div>
<h3 className="font-sans font-normal text-xl sm:text-2xl lg:text-3xl text-black tracking-[-1.2px] sm:tracking-[-1.4px] lg:tracking-[-1.6px]! mb-4 sm:mb-6">
Developer Resources
Resources
</h3>
<nav className="space-y-3 sm:space-y-4">
{footerLinks.developerResources.map((link) => (
{footerLinks.resources.map((link) => (
<Link
key={link.href}
href={link.href}
target={link.external ? "_blank" : undefined}
rel={link.external ? "noopener noreferrer" : undefined}
className="block font-sans font-normal text-sm sm:text-base lg:text-lg text-black tracking-[-0.8px] sm:tracking-[-0.9px] lg:tracking-[-1px]! hover:text-[var(--primary)] transition-colors"
>
{link.label}

View file

@ -11,7 +11,7 @@ import { X, Menu } from "lucide-react";
const navItems = [
{ href: "https://docs.plano.katanemo.com/getting-started/installation", label: "start locally" },
{ href: "https://docs.plano.katanemo.com", label: "docs" },
{ href: "/model-research", label: "models research" },
{ href: "/research", label: "research" },
{ href: "/blog", label: "blog" },
];