diff --git a/www/package-lock.json b/www/package-lock.json index 2f8af1cd..cb9b6c0a 100644 --- a/www/package-lock.json +++ b/www/package-lock.json @@ -8,6 +8,7 @@ "name": "website", "version": "0.1.0", "dependencies": { + "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-slot": "^1.2.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -827,6 +828,12 @@ "node": ">= 10" } }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -842,6 +849,213 @@ } } }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", @@ -860,6 +1074,91 @@ } } }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@swc/helpers": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", @@ -1164,12 +1463,24 @@ "version": "19.2.2", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", - "dev": true, + "devOptional": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" } }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001751", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", @@ -1234,6 +1545,12 @@ "node": ">=8" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, "node_modules/enhanced-resolve": { "version": "5.18.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", @@ -1275,6 +1592,15 @@ } } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -1741,6 +2067,75 @@ "react": "^19.2.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -1902,6 +2297,49 @@ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } } } } diff --git a/www/package.json b/www/package.json index e5e31613..e04749db 100644 --- a/www/package.json +++ b/www/package.json @@ -10,6 +10,7 @@ "format": "biome format --write" }, "dependencies": { + "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-slot": "^1.2.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/www/public/HowItWorks.svg b/www/public/HowItWorks.svg new file mode 100644 index 00000000..2b001351 --- /dev/null +++ b/www/public/HowItWorks.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/www/public/NetworkPathDiagram.svg b/www/public/NetworkPathDiagram.svg new file mode 100644 index 00000000..0177f44e --- /dev/null +++ b/www/public/NetworkPathDiagram.svg @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/www/public/fonts/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf b/www/public/fonts/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf new file mode 100644 index 00000000..6232aaa8 Binary files /dev/null and b/www/public/fonts/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf differ diff --git a/www/src/app/globals.css b/www/src/app/globals.css index 9396a0d4..cbb7d1a2 100644 --- a/www/src/app/globals.css +++ b/www/src/app/globals.css @@ -12,6 +12,14 @@ font-display: swap; } +@font-face { + font-family: "IBM Plex Sans"; + src: url("/fonts/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf") format("truetype-variations"); + font-weight: 100 700; /* Variable font weight range */ + font-style: italic; + font-display: swap; +} + @font-face { font-family: "JetBrains Mono"; src: url("/fonts/JetBrainsMono-Regular.woff2") format("woff2"); diff --git a/www/src/app/page.tsx b/www/src/app/page.tsx index f6bd5518..bad94005 100644 --- a/www/src/app/page.tsx +++ b/www/src/app/page.tsx @@ -7,6 +7,7 @@ import { IntroSection } from "@/components/IntroSection"; import { IdeaToAgentSection } from "@/components/IdeaToAgentSection"; import { UseCasesSection } from "@/components/UseCasesSection"; import { VerticalCarouselSection } from "@/components/VerticalCarouselSection"; +import { HowItWorksSection } from "@/components/HowItWorksSection"; import { UnlockPotentialSection } from "@/components/UnlockPotentialSection"; import { Footer } from "@/components/Footer"; import { LogoCloud } from "@/components/LogoCloud"; @@ -22,6 +23,7 @@ export default function Home() { + {/* Rest of the sections will be refactored next */} diff --git a/www/src/components/Hero.tsx b/www/src/components/Hero.tsx index 128975fc..336734ae 100644 --- a/www/src/components/Hero.tsx +++ b/www/src/components/Hero.tsx @@ -14,23 +14,23 @@ export function Hero() { {/* Version Badge */}
- v0.3.12 + v0.4 - RAG Agent Launch! + Unified /v1/responses API with state management
{/* Main Heading */}

- The AI-native - network for agents + Models-native + dataplane for agents

{/* Subheading with CTA Buttons on the right */}
-

- Build and scale AI agents without handling the low-level plumbing. +

+ Build agents faster, and scale them reliably by offloading the plumbing work in AI agents.

{/* CTA Buttons */} diff --git a/www/src/components/HowItWorksSection.tsx b/www/src/components/HowItWorksSection.tsx new file mode 100644 index 00000000..e99c5fa3 --- /dev/null +++ b/www/src/components/HowItWorksSection.tsx @@ -0,0 +1,39 @@ +"use client"; + +import React from "react"; +import Image from "next/image"; + +export function HowItWorksSection() { + return ( +
+
+
+ {/* Header and Description */} +
+

+ How it works +

+
+

+ Plano offers a delightful developer experience with a simple configuration file that describes the types of prompts your agentic app supports, a set of APIs that need to be plugged in for agentic scenarios (including retrieval queries) and your choice of LLMs. +

+
+
+ + {/* Large Diagram */} +
+ How Plano Works Diagram +
+
+
+
+ ); +} + diff --git a/www/src/components/IdeaToAgentSection.tsx b/www/src/components/IdeaToAgentSection.tsx index b0b10e60..e99d5e3c 100644 --- a/www/src/components/IdeaToAgentSection.tsx +++ b/www/src/components/IdeaToAgentSection.tsx @@ -9,35 +9,35 @@ const carouselData = [ id: 1, category: "LAUNCH FASTER", title: "Focus on core objectives", - description: "Plano handles the heavy lifting for agentic apps with purpose-built LLMs that automate request clarification, query routing, and data extraction. Ship faster without juggling prompt engineering or infrastructure details.", + 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" }, { id: 2, - category: "SCALE EFFICIENTLY", - title: "Build without limits", - description: "From prototype to production, Plano scales with your needs. Handle thousands of concurrent requests while maintaining consistent performance and reliability across your agent network.", - image: "/ShipConfidently.svg" - }, - { - id: 3, - category: "DEPLOY CONFIDENTLY", - title: "Production-ready infrastructure", - description: "Enterprise-grade security, monitoring, and governance built-in. Deploy your agents with confidence knowing they're protected by battle-tested infrastructure and compliance frameworks.", + category: "BUILD WITH CHOICE", + title: "Rapidly incorporate LLMs", + 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" }, { - id: 4, - category: "INTEGRATE SEAMLESSLY", - title: "Connect everything", - description: "Unified API access across all major LLM providers. Switch between models, combine capabilities, and route requests intelligently without vendor lock-in or complex integrations.", + id: 3, + category: "RICH LEARNING SIGNALS", + title: "Hyper-rich agent traces and logs", + 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" }, + { + id: 4, + category: "SHIP CONFIDENTLY", + title: "Centrally apply guardrail policies", + 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" + }, { id: 5, - category: "OPTIMIZE CONTINUOUSLY", - title: "Learn and improve", - description: "Built-in analytics and feedback loops help your agents get smarter over time. Track performance, identify bottlenecks, and optimize workflows with real-time insights and automated improvements.", + category: "SCALABLE ARCHITECTURE", + title: "Protocol-Native Infrastructure", + 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" } ]; diff --git a/www/src/components/IntroSection.tsx b/www/src/components/IntroSection.tsx index 0ef69f3c..6e29d8a1 100644 --- a/www/src/components/IntroSection.tsx +++ b/www/src/components/IntroSection.tsx @@ -1,34 +1,47 @@ import React from "react"; -import { AsciiDiagram } from "@/components/AsciiDiagram"; -import { diagrams } from "@/data/diagrams"; +import Image from "next/image"; export function IntroSection() { return (
-
+
{/* Left Content */}
{/* Heading */} +

+ WHY PLANO? +

- Go beyond AI nascent demos + Ship prototypes to production + —fast.

{/* Body Text */}

- Plano is the infrastructure layer for building, scaling, and routing AI agents. It sits between your app and your models, enforcing safety guardrails, orchestrating multi-agent workflows, and unifying access across large language models. -

-
-

- Developers use Plano to build faster, platform teams use it to unify governance, and AI leads use it to run continuously learning systems that stay aligned, safe, and performant. From SaaS backends to distributed ecosystems, Plano turns raw agent logic into something you can deploy, monitor, and evolve in production. + Plano is a framework-friendly proxy server and dataplane for agents, + deployed as a sidecar. Plano handles the critical plumbing work in AI + like agent routing and orchestration, comprehensive traces for agentic + interactions, guardrail hooks, unified APIs for LLMs — so developers + can focus more on modeling workflows, product teams can accelerate + feedback loops for reinforcement learning and engineering teams can + standardize policies and access controls across every agent and LLM for + safer, more reliable scaling.

{/* Right Diagram */} -
- +
+ Network Path Diagram
diff --git a/www/src/components/Navbar.tsx b/www/src/components/Navbar.tsx index 5b747fe2..14adfa4c 100644 --- a/www/src/components/Navbar.tsx +++ b/www/src/components/Navbar.tsx @@ -7,9 +7,11 @@ import { Button } from "./ui/button"; import { cn } from "@/lib/utils"; const navItems = [ + { href: "/start", label: "start locally" }, { href: "/docs", label: "docs" }, - { href: "/pricing", label: "pricing" }, + { href: "/model-research", label: "models research" }, { href: "/blog", label: "blog" }, + { href: "/why", label: "why plano?" }, ]; export function Navbar() { diff --git a/www/src/components/UnlockPotentialSection.tsx b/www/src/components/UnlockPotentialSection.tsx index ddea25df..7b436f6f 100644 --- a/www/src/components/UnlockPotentialSection.tsx +++ b/www/src/components/UnlockPotentialSection.tsx @@ -17,8 +17,9 @@ export function UnlockPotentialSection({
-

- Unlock the full potential of your applications with Plano. +

+ Focus on prompting, not plumbing
+ Build with plano, get started in less than a minute.

diff --git a/www/src/components/UseCasesSection.tsx b/www/src/components/UseCasesSection.tsx index 9a3148e2..07a408a3 100644 --- a/www/src/components/UseCasesSection.tsx +++ b/www/src/components/UseCasesSection.tsx @@ -1,35 +1,60 @@ -import React from "react"; +"use client"; + +import React, { useState } from "react"; import { ArrowRightIcon } from "lucide-react"; import { Button } from "./ui/button"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "./ui/dialog"; +import { motion, AnimatePresence } from "framer-motion"; -const useCasesData = [ +interface UseCase { + id: number; + category: string; + title: string; + summary: string; + fullContent: string; +} + +const useCasesData: UseCase[] = [ { id: 1, - category: "FROM SAAS TO AGENTS", - title: "Transform software into active agents", - link: "Learn more" + category: "AGENT ORCHESTRATION", + title: "Multi-agent systems without framework lock-in", + summary: "Seamless routing and orchestration for complex agent interactions", + fullContent: "Plano manages agent routing and orchestration without framework dependencies, allowing seamless multi-agent interactions. This is ideal for building complex systems like automated customer support or data processing pipelines, where agents hand off tasks efficiently to deliver end-to-end solutions faster." }, { id: 2, - category: "AGENTIC TASKS", - title: "Train models through live feedback", - link: "Learn more" + category: "CONTEXT ENGINEERING", + title: "Reusable filters for smarter agents", + summary: "Inject data, reformulate queries, and enforce policies efficiently", + fullContent: "Plano's filter chain encourages reuse and decoupling for context engineering tasks like injecting data, reformulating queries, and enforcing policy before calls reach an agent or LLM. This means faster debugging, cleaner architecture, and more accurate, on-policy agents —without bespoke glue code." }, { id: 3, - category: "AGENTIC ROUTING", - title: "Route logic across smart agents", - link: "Learn more" + category: "REINFORCEMENT LEARNING", + title: "Production signals for continuous improvement", + summary: "Capture rich traces to accelerate training and refinement", + fullContent: "Plano captures hyper-rich tracing and log samples from production traffic, feeding into reinforcement learning and fine-tuning cycles. This accelerates iteration in areas like recommendation engines, helping teams quickly identify failures, refine prompts, and boost agent effectiveness based on real-user signals." }, { id: 4, - category: "SAAS INTEGRATIONS", - title: "Design networks of intelligent agents", - link: "Learn more" + category: "SECURITY", + title: "Built-in guardrails and centralized policies", + summary: "Safe scaling with jailbreak detection and access controls", + fullContent: "With built-in guardrails, centralized policies, and access controls, Plano ensures safe scaling across LLMs, detecting issues like jailbreak attempts. This is critical for deployments in regulated fields like finance or healthcare, and minimizing risks while standardizing reliability and security of agents." + }, + { + id: 5, + category: "ON-PREMISES", + title: "Full data control in regulated environments", + summary: "Deploy on private infrastructure without compromising features", + fullContent: "Plano's lightweight sidecar model deploys effortlessly on your private infrastructure, empowering teams in regulated sectors to maintain full data control while benefiting from unified LLM access, custom filter chains, and production-grade tracing—without compromising on security or scalability." } ]; export function UseCasesSection() { + const [selectedUseCase, setSelectedUseCase] = useState(null); + return (
@@ -53,37 +78,74 @@ export function UseCasesSection() {
- {/* 4 Box Grid */} -
+ {/* 5 Card Grid - Horizontal Row */} +
{useCasesData.map((useCase) => ( -
setSelectedUseCase(useCase)} > {/* Category */}
-

+

{useCase.category}

{/* Title */} -

+

{useCase.title}

{/* Learn More Link */}
-
-
+ ))}
-
+ + {/* Modal */} + !open && setSelectedUseCase(null)}> + + {selectedUseCase && ( + + + +
+

+ USE CASE +

+ + {selectedUseCase.category} + +
+ + {selectedUseCase.fullContent} + +
+
+ +
+
+
+ )} +
+
); } diff --git a/www/src/components/ui/dialog.tsx b/www/src/components/ui/dialog.tsx new file mode 100644 index 00000000..d9ccec91 --- /dev/null +++ b/www/src/components/ui/dialog.tsx @@ -0,0 +1,143 @@ +"use client" + +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { XIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Dialog({ + ...props +}: React.ComponentProps) { + return +} + +function DialogTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function DialogPortal({ + ...props +}: React.ComponentProps) { + return +} + +function DialogClose({ + ...props +}: React.ComponentProps) { + return +} + +function DialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DialogContent({ + className, + children, + showCloseButton = true, + ...props +}: React.ComponentProps & { + showCloseButton?: boolean +}) { + return ( + + + + {children} + {showCloseButton && ( + + + Close + + )} + + + ) +} + +function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +}