diff --git a/package.json b/package.json index 0088028e..52cb71e8 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "@sentry/astro": "^10.42.0", "@shikijs/transformers": "^3.15.0", "@sindresorhus/slugify": "^3.0.0", - "@tailwindcss/forms": "^0.5.10", "@tailwindcss/typography": "^0.5.19", "@types/json-schema": "^7.0.15", "@types/react": "^19.0.0", @@ -57,8 +56,6 @@ "feed": "^5.1.0", "focus-visible": "^5.2.1", "framer-motion": "^12.23.24", - "fuse.js": "^7.1.0", - "jszip": "^3.10.1", "lodash": "^4.17.21", "lucide-react": "^0.439.0", "mdast-util-to-string": "^4.0.0", @@ -70,8 +67,6 @@ "react": "^19.2.0", "react-chartjs-2": "^5.3.1", "react-dom": "^19.2.0", - "react-github-btn": "^1.4.0", - "react-highlight-words": "^0.21.0", "react-markdown": "^10.1.0", "rehype-mermaid": "^3.0.0", "remark-gfm": "^4.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4d660442..18bbc2d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,9 +59,6 @@ importers: '@sindresorhus/slugify': specifier: ^3.0.0 version: 3.0.0 - '@tailwindcss/forms': - specifier: ^0.5.10 - version: 0.5.11(tailwindcss@3.4.19(tsx@4.23.12)(yaml@2.9.0)) '@tailwindcss/typography': specifier: ^0.5.19 version: 0.5.20(tailwindcss@3.4.19(tsx@4.23.12)(yaml@2.9.0)) @@ -110,12 +107,6 @@ importers: framer-motion: specifier: ^12.23.24 version: 12.43.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - fuse.js: - specifier: ^7.1.0 - version: 7.5.0 - jszip: - specifier: ^3.10.1 - version: 3.10.1 lodash: specifier: ^4.17.21 version: 4.18.1 @@ -149,12 +140,6 @@ importers: react-dom: specifier: ^19.2.0 version: 19.2.8(react@19.2.8) - react-github-btn: - specifier: ^1.4.0 - version: 1.4.0(react@19.2.8) - react-highlight-words: - specifier: ^0.21.0 - version: 0.21.0(react@19.2.8) react-markdown: specifier: ^10.1.0 version: 10.1.0(@types/react@19.2.18)(react@19.2.8) @@ -2635,11 +2620,6 @@ packages: peerDependencies: tailwindcss: '>=3.2.0' - '@tailwindcss/forms@0.5.11': - resolution: {integrity: sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==} - peerDependencies: - tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' - '@tailwindcss/typography@0.5.20': resolution: {integrity: sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw==} peerDependencies: @@ -3838,10 +3818,6 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - fuse.js@7.5.0: - resolution: {integrity: sha512-sQtrEfA+ez/3G0cCZecF70oqpCRttCexYUG4mUrtWL49ULUzUyxokt5kyqwtKzj1270RaKih+hcP3qLcumccow==} - engines: {node: '>=10'} - gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -4159,9 +4135,6 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jszip@3.10.1: - resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} - katex@0.16.47: resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} hasBin: true @@ -4929,16 +4902,6 @@ packages: peerDependencies: react: ^19.2.8 - react-github-btn@1.4.0: - resolution: {integrity: sha512-lV4FYClAfjWnBfv0iNlJUGhamDgIq6TayD0kPZED6VzHWdpcHmPfsYOZ/CFwLfPv4Zp+F4m8QKTj0oy2HjiGXg==} - peerDependencies: - react: '>=16.3.0' - - react-highlight-words@0.21.0: - resolution: {integrity: sha512-SdWEeU9fIINArEPO1rO5OxPyuhdEKZQhHzZZP1ie6UeXQf+CjycT1kWaB+9bwGcVbR0NowuHK3RqgqNg6bgBDQ==} - peerDependencies: - react: ^0.14.0 || ^15.0.0 || ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0 - react-hook-form@7.85.0: resolution: {integrity: sha512-U2MTriFXnclmV4rOE20p2DcRFv5WEg3FIcBFOKcOLFHDVvGIMPvLTkTWefUsonmlaVy23khVDxDWym6uJVGOzw==} engines: {node: '>=18.0.0'} @@ -7896,11 +7859,6 @@ snapshots: dependencies: tailwindcss: 3.4.19(tsx@4.23.12)(yaml@2.9.0) - '@tailwindcss/forms@0.5.11(tailwindcss@3.4.19(tsx@4.23.12)(yaml@2.9.0))': - dependencies: - mini-svg-data-uri: 1.4.4 - tailwindcss: 3.4.19(tsx@4.23.12)(yaml@2.9.0) - '@tailwindcss/typography@0.5.20(tailwindcss@3.4.19(tsx@4.23.12)(yaml@2.9.0))': dependencies: postcss-selector-parser: 6.0.10 @@ -9353,8 +9311,6 @@ snapshots: function-bind@1.1.2: {} - fuse.js@7.5.0: {} - gensync@1.0.0-beta.2: {} get-east-asian-width@1.6.0: {} @@ -9717,13 +9673,6 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jszip@3.10.1: - dependencies: - lie: 3.3.0 - pako: 1.0.11 - readable-stream: 2.3.8 - setimmediate: 1.0.5 - katex@0.16.47: dependencies: commander: 8.3.0 @@ -10675,17 +10624,6 @@ snapshots: react: 19.2.8 scheduler: 0.27.0 - react-github-btn@1.4.0(react@19.2.8): - dependencies: - github-buttons: 2.33.0 - react: 19.2.8 - - react-highlight-words@0.21.0(react@19.2.8): - dependencies: - highlight-words-core: 1.2.3 - memoize-one: 4.0.3 - react: 19.2.8 - react-hook-form@7.85.0(react@19.2.8): dependencies: react: 19.2.8 diff --git a/public/fonts/cartridge/Cartridge-Bold.otf b/public/fonts/cartridge/Cartridge-Bold.otf deleted file mode 100644 index bb35bf1e..00000000 Binary files a/public/fonts/cartridge/Cartridge-Bold.otf and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-Bold.woff b/public/fonts/cartridge/Cartridge-Bold.woff deleted file mode 100644 index 5fce0ec2..00000000 Binary files a/public/fonts/cartridge/Cartridge-Bold.woff and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-Bold.woff2 b/public/fonts/cartridge/Cartridge-Bold.woff2 deleted file mode 100644 index 62ccbd9c..00000000 Binary files a/public/fonts/cartridge/Cartridge-Bold.woff2 and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-BoldRough.otf b/public/fonts/cartridge/Cartridge-BoldRough.otf deleted file mode 100644 index 8053dc98..00000000 Binary files a/public/fonts/cartridge/Cartridge-BoldRough.otf and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-BoldRough.woff b/public/fonts/cartridge/Cartridge-BoldRough.woff deleted file mode 100644 index 6d00d799..00000000 Binary files a/public/fonts/cartridge/Cartridge-BoldRough.woff and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-BoldRough.woff2 b/public/fonts/cartridge/Cartridge-BoldRough.woff2 deleted file mode 100644 index f645fac5..00000000 Binary files a/public/fonts/cartridge/Cartridge-BoldRough.woff2 and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-Regular.otf b/public/fonts/cartridge/Cartridge-Regular.otf deleted file mode 100644 index 219a299d..00000000 Binary files a/public/fonts/cartridge/Cartridge-Regular.otf and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-Regular.woff b/public/fonts/cartridge/Cartridge-Regular.woff deleted file mode 100644 index aaf1e62e..00000000 Binary files a/public/fonts/cartridge/Cartridge-Regular.woff and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-Regular.woff2 b/public/fonts/cartridge/Cartridge-Regular.woff2 deleted file mode 100644 index 07b998c3..00000000 Binary files a/public/fonts/cartridge/Cartridge-Regular.woff2 and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-Rough.otf b/public/fonts/cartridge/Cartridge-Rough.otf deleted file mode 100644 index 66f35485..00000000 Binary files a/public/fonts/cartridge/Cartridge-Rough.otf and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-Rough.woff b/public/fonts/cartridge/Cartridge-Rough.woff deleted file mode 100644 index 8fa79d88..00000000 Binary files a/public/fonts/cartridge/Cartridge-Rough.woff and /dev/null differ diff --git a/public/fonts/cartridge/Cartridge-Rough.woff2 b/public/fonts/cartridge/Cartridge-Rough.woff2 deleted file mode 100644 index e53c64de..00000000 Binary files a/public/fonts/cartridge/Cartridge-Rough.woff2 and /dev/null differ diff --git a/public/fonts/darker-grotesque/DarkerGrotesque-Black.ttf b/public/fonts/darker-grotesque/DarkerGrotesque-Black.ttf deleted file mode 100644 index 46131bef..00000000 Binary files a/public/fonts/darker-grotesque/DarkerGrotesque-Black.ttf and /dev/null differ diff --git a/public/fonts/darker-grotesque/DarkerGrotesque-Bold.ttf b/public/fonts/darker-grotesque/DarkerGrotesque-Bold.ttf deleted file mode 100644 index 73e5421f..00000000 Binary files a/public/fonts/darker-grotesque/DarkerGrotesque-Bold.ttf and /dev/null differ diff --git a/public/fonts/darker-grotesque/DarkerGrotesque-ExtraBold.ttf b/public/fonts/darker-grotesque/DarkerGrotesque-ExtraBold.ttf deleted file mode 100644 index 9ffe7077..00000000 Binary files a/public/fonts/darker-grotesque/DarkerGrotesque-ExtraBold.ttf and /dev/null differ diff --git a/public/fonts/darker-grotesque/DarkerGrotesque-Light.ttf b/public/fonts/darker-grotesque/DarkerGrotesque-Light.ttf deleted file mode 100644 index 9239989f..00000000 Binary files a/public/fonts/darker-grotesque/DarkerGrotesque-Light.ttf and /dev/null differ diff --git a/public/fonts/darker-grotesque/DarkerGrotesque-Medium.ttf b/public/fonts/darker-grotesque/DarkerGrotesque-Medium.ttf deleted file mode 100644 index 9ebddcc8..00000000 Binary files a/public/fonts/darker-grotesque/DarkerGrotesque-Medium.ttf and /dev/null differ diff --git a/public/fonts/darker-grotesque/DarkerGrotesque-Regular.ttf b/public/fonts/darker-grotesque/DarkerGrotesque-Regular.ttf deleted file mode 100644 index 29a362a3..00000000 Binary files a/public/fonts/darker-grotesque/DarkerGrotesque-Regular.ttf and /dev/null differ diff --git a/public/fonts/darker-grotesque/DarkerGrotesque-SemiBold.ttf b/public/fonts/darker-grotesque/DarkerGrotesque-SemiBold.ttf deleted file mode 100644 index 845954c4..00000000 Binary files a/public/fonts/darker-grotesque/DarkerGrotesque-SemiBold.ttf and /dev/null differ diff --git a/public/fonts/gloria-hallelujah/GloriaHallelujah-Regular.ttf b/public/fonts/gloria-hallelujah/GloriaHallelujah-Regular.ttf deleted file mode 100644 index 3c68ec0a..00000000 Binary files a/public/fonts/gloria-hallelujah/GloriaHallelujah-Regular.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-Bold.ttf b/public/fonts/open-sans/OpenSans-Bold.ttf deleted file mode 100644 index 16581634..00000000 Binary files a/public/fonts/open-sans/OpenSans-Bold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-BoldItalic.ttf b/public/fonts/open-sans/OpenSans-BoldItalic.ttf deleted file mode 100644 index 23e6b86c..00000000 Binary files a/public/fonts/open-sans/OpenSans-BoldItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-ExtraBold.ttf b/public/fonts/open-sans/OpenSans-ExtraBold.ttf deleted file mode 100644 index c1799c5a..00000000 Binary files a/public/fonts/open-sans/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-ExtraBoldItalic.ttf b/public/fonts/open-sans/OpenSans-ExtraBoldItalic.ttf deleted file mode 100644 index 683066a0..00000000 Binary files a/public/fonts/open-sans/OpenSans-ExtraBoldItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-Italic.ttf b/public/fonts/open-sans/OpenSans-Italic.ttf deleted file mode 100644 index 222edf6d..00000000 Binary files a/public/fonts/open-sans/OpenSans-Italic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-Light.ttf b/public/fonts/open-sans/OpenSans-Light.ttf deleted file mode 100644 index 3556a925..00000000 Binary files a/public/fonts/open-sans/OpenSans-Light.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-LightItalic.ttf b/public/fonts/open-sans/OpenSans-LightItalic.ttf deleted file mode 100644 index 02a66f1e..00000000 Binary files a/public/fonts/open-sans/OpenSans-LightItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-Medium.ttf b/public/fonts/open-sans/OpenSans-Medium.ttf deleted file mode 100644 index 5fe31edb..00000000 Binary files a/public/fonts/open-sans/OpenSans-Medium.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-MediumItalic.ttf b/public/fonts/open-sans/OpenSans-MediumItalic.ttf deleted file mode 100644 index f9dfd7ef..00000000 Binary files a/public/fonts/open-sans/OpenSans-MediumItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-Regular.ttf b/public/fonts/open-sans/OpenSans-Regular.ttf deleted file mode 100644 index 4d3ff730..00000000 Binary files a/public/fonts/open-sans/OpenSans-Regular.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-SemiBold.ttf b/public/fonts/open-sans/OpenSans-SemiBold.ttf deleted file mode 100644 index be167af4..00000000 Binary files a/public/fonts/open-sans/OpenSans-SemiBold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans-SemiBoldItalic.ttf b/public/fonts/open-sans/OpenSans-SemiBoldItalic.ttf deleted file mode 100644 index 5196de8a..00000000 Binary files a/public/fonts/open-sans/OpenSans-SemiBoldItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-Bold.ttf b/public/fonts/open-sans/OpenSans_Condensed-Bold.ttf deleted file mode 100644 index 6c5821a6..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-Bold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-BoldItalic.ttf b/public/fonts/open-sans/OpenSans_Condensed-BoldItalic.ttf deleted file mode 100644 index 5574593f..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-BoldItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-ExtraBold.ttf b/public/fonts/open-sans/OpenSans_Condensed-ExtraBold.ttf deleted file mode 100644 index d1694698..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-ExtraBold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-ExtraBoldItalic.ttf b/public/fonts/open-sans/OpenSans_Condensed-ExtraBoldItalic.ttf deleted file mode 100644 index 06363fc8..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-ExtraBoldItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-Italic.ttf b/public/fonts/open-sans/OpenSans_Condensed-Italic.ttf deleted file mode 100644 index b14ea98a..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-Italic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-Light.ttf b/public/fonts/open-sans/OpenSans_Condensed-Light.ttf deleted file mode 100644 index d1b245e6..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-Light.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-LightItalic.ttf b/public/fonts/open-sans/OpenSans_Condensed-LightItalic.ttf deleted file mode 100644 index 6902a9b8..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-LightItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-Medium.ttf b/public/fonts/open-sans/OpenSans_Condensed-Medium.ttf deleted file mode 100644 index c907874b..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-Medium.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-MediumItalic.ttf b/public/fonts/open-sans/OpenSans_Condensed-MediumItalic.ttf deleted file mode 100644 index 2acad13d..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-MediumItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-Regular.ttf b/public/fonts/open-sans/OpenSans_Condensed-Regular.ttf deleted file mode 100644 index 71cf4b52..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-Regular.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-SemiBold.ttf b/public/fonts/open-sans/OpenSans_Condensed-SemiBold.ttf deleted file mode 100644 index 6a8ed8db..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-SemiBold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_Condensed-SemiBoldItalic.ttf b/public/fonts/open-sans/OpenSans_Condensed-SemiBoldItalic.ttf deleted file mode 100644 index d8791e12..00000000 Binary files a/public/fonts/open-sans/OpenSans_Condensed-SemiBoldItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-Bold.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-Bold.ttf deleted file mode 100644 index ee71b085..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-Bold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-BoldItalic.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-BoldItalic.ttf deleted file mode 100644 index f24bd0f8..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-BoldItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-ExtraBold.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-ExtraBold.ttf deleted file mode 100644 index 5537e790..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-ExtraBold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-ExtraBoldItalic.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-ExtraBoldItalic.ttf deleted file mode 100644 index 72a3bcf4..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-ExtraBoldItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-Italic.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-Italic.ttf deleted file mode 100644 index b45bbdc4..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-Italic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-Light.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-Light.ttf deleted file mode 100644 index 646289e3..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-Light.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-LightItalic.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-LightItalic.ttf deleted file mode 100644 index dd5bc94a..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-LightItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-Medium.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-Medium.ttf deleted file mode 100644 index e65a8906..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-Medium.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-MediumItalic.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-MediumItalic.ttf deleted file mode 100644 index 6640b617..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-MediumItalic.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-Regular.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-Regular.ttf deleted file mode 100644 index a2df2097..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-Regular.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-SemiBold.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-SemiBold.ttf deleted file mode 100644 index 17898426..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-SemiBold.ttf and /dev/null differ diff --git a/public/fonts/open-sans/OpenSans_SemiCondensed-SemiBoldItalic.ttf b/public/fonts/open-sans/OpenSans_SemiCondensed-SemiBoldItalic.ttf deleted file mode 100644 index f297d147..00000000 Binary files a/public/fonts/open-sans/OpenSans_SemiCondensed-SemiBoldItalic.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-Black.ttf b/public/fonts/outfit/Outfit-Black.ttf deleted file mode 100644 index 487752bb..00000000 Binary files a/public/fonts/outfit/Outfit-Black.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-Bold.ttf b/public/fonts/outfit/Outfit-Bold.ttf deleted file mode 100644 index 3491286d..00000000 Binary files a/public/fonts/outfit/Outfit-Bold.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-ExtraBold.ttf b/public/fonts/outfit/Outfit-ExtraBold.ttf deleted file mode 100644 index 0977ed52..00000000 Binary files a/public/fonts/outfit/Outfit-ExtraBold.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-ExtraLight.ttf b/public/fonts/outfit/Outfit-ExtraLight.ttf deleted file mode 100644 index e584ecb3..00000000 Binary files a/public/fonts/outfit/Outfit-ExtraLight.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-Light.ttf b/public/fonts/outfit/Outfit-Light.ttf deleted file mode 100644 index f85a289f..00000000 Binary files a/public/fonts/outfit/Outfit-Light.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-Medium.ttf b/public/fonts/outfit/Outfit-Medium.ttf deleted file mode 100644 index 7ae796b9..00000000 Binary files a/public/fonts/outfit/Outfit-Medium.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-Regular.ttf b/public/fonts/outfit/Outfit-Regular.ttf deleted file mode 100644 index 826899cf..00000000 Binary files a/public/fonts/outfit/Outfit-Regular.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-SemiBold.ttf b/public/fonts/outfit/Outfit-SemiBold.ttf deleted file mode 100644 index 6b37eeb6..00000000 Binary files a/public/fonts/outfit/Outfit-SemiBold.ttf and /dev/null differ diff --git a/public/fonts/outfit/Outfit-Thin.ttf b/public/fonts/outfit/Outfit-Thin.ttf deleted file mode 100644 index c4b9d557..00000000 Binary files a/public/fonts/outfit/Outfit-Thin.ttf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-Black.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-Black.otf deleted file mode 100644 index faaebee5..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-Black.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-BlackItalic.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-BlackItalic.otf deleted file mode 100644 index 66183854..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-BlackItalic.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-Bold.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-Bold.otf deleted file mode 100644 index 293e9a63..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-Bold.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-BoldItalic.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-BoldItalic.otf deleted file mode 100644 index f62e4d5c..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-BoldItalic.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-Extrabold.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-Extrabold.otf deleted file mode 100644 index c11d6b48..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-Extrabold.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-ExtraboldItalic.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-ExtraboldItalic.otf deleted file mode 100644 index d0e48029..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-ExtraboldItalic.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-Regular.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-Regular.otf deleted file mode 100644 index ae2dcb4b..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-Regular.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-RegularItalic.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-RegularItalic.otf deleted file mode 100644 index cc489ce8..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-RegularItalic.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-Semibold.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-Semibold.otf deleted file mode 100644 index 68379a2a..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-Semibold.otf and /dev/null differ diff --git a/public/fonts/perfectly-nineties/PerfectlyNineties-SemiboldItalic.otf b/public/fonts/perfectly-nineties/PerfectlyNineties-SemiboldItalic.otf deleted file mode 100644 index 9533f0bb..00000000 Binary files a/public/fonts/perfectly-nineties/PerfectlyNineties-SemiboldItalic.otf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-Black.ttf b/public/fonts/prompt/Prompt-Black.ttf deleted file mode 100644 index 8e0ec4ac..00000000 Binary files a/public/fonts/prompt/Prompt-Black.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-BlackItalic.ttf b/public/fonts/prompt/Prompt-BlackItalic.ttf deleted file mode 100644 index 82d80ac6..00000000 Binary files a/public/fonts/prompt/Prompt-BlackItalic.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-Bold.ttf b/public/fonts/prompt/Prompt-Bold.ttf deleted file mode 100644 index 07eacc77..00000000 Binary files a/public/fonts/prompt/Prompt-Bold.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-BoldItalic.ttf b/public/fonts/prompt/Prompt-BoldItalic.ttf deleted file mode 100644 index 160b9a42..00000000 Binary files a/public/fonts/prompt/Prompt-BoldItalic.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-ExtraBold.ttf b/public/fonts/prompt/Prompt-ExtraBold.ttf deleted file mode 100644 index 178e026e..00000000 Binary files a/public/fonts/prompt/Prompt-ExtraBold.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-ExtraBoldItalic.ttf b/public/fonts/prompt/Prompt-ExtraBoldItalic.ttf deleted file mode 100644 index a493db21..00000000 Binary files a/public/fonts/prompt/Prompt-ExtraBoldItalic.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-ExtraLight.ttf b/public/fonts/prompt/Prompt-ExtraLight.ttf deleted file mode 100644 index 83f5a8e2..00000000 Binary files a/public/fonts/prompt/Prompt-ExtraLight.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-ExtraLightItalic.ttf b/public/fonts/prompt/Prompt-ExtraLightItalic.ttf deleted file mode 100644 index fcb97dfc..00000000 Binary files a/public/fonts/prompt/Prompt-ExtraLightItalic.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-Italic.ttf b/public/fonts/prompt/Prompt-Italic.ttf deleted file mode 100644 index 520a2cfe..00000000 Binary files a/public/fonts/prompt/Prompt-Italic.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-Light.ttf b/public/fonts/prompt/Prompt-Light.ttf deleted file mode 100644 index 6a86f4a7..00000000 Binary files a/public/fonts/prompt/Prompt-Light.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-LightItalic.ttf b/public/fonts/prompt/Prompt-LightItalic.ttf deleted file mode 100644 index e0c3e37b..00000000 Binary files a/public/fonts/prompt/Prompt-LightItalic.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-Medium.ttf b/public/fonts/prompt/Prompt-Medium.ttf deleted file mode 100644 index 1adf3314..00000000 Binary files a/public/fonts/prompt/Prompt-Medium.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-MediumItalic.ttf b/public/fonts/prompt/Prompt-MediumItalic.ttf deleted file mode 100644 index 0bee9912..00000000 Binary files a/public/fonts/prompt/Prompt-MediumItalic.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-Regular.ttf b/public/fonts/prompt/Prompt-Regular.ttf deleted file mode 100644 index a4bf5384..00000000 Binary files a/public/fonts/prompt/Prompt-Regular.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-SemiBold.ttf b/public/fonts/prompt/Prompt-SemiBold.ttf deleted file mode 100644 index 8de4f952..00000000 Binary files a/public/fonts/prompt/Prompt-SemiBold.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-SemiBoldItalic.ttf b/public/fonts/prompt/Prompt-SemiBoldItalic.ttf deleted file mode 100644 index 7b7f9197..00000000 Binary files a/public/fonts/prompt/Prompt-SemiBoldItalic.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-Thin.ttf b/public/fonts/prompt/Prompt-Thin.ttf deleted file mode 100644 index a27a3ef7..00000000 Binary files a/public/fonts/prompt/Prompt-Thin.ttf and /dev/null differ diff --git a/public/fonts/prompt/Prompt-ThinItalic.ttf b/public/fonts/prompt/Prompt-ThinItalic.ttf deleted file mode 100644 index 642167a2..00000000 Binary files a/public/fonts/prompt/Prompt-ThinItalic.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-Black.ttf b/public/fonts/saira-condensed/SairaCondensed-Black.ttf deleted file mode 100644 index 2aa0fc8b..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-Black.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-Bold.ttf b/public/fonts/saira-condensed/SairaCondensed-Bold.ttf deleted file mode 100644 index cb882324..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-Bold.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-ExtraBold.ttf b/public/fonts/saira-condensed/SairaCondensed-ExtraBold.ttf deleted file mode 100644 index beab2d98..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-ExtraBold.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-ExtraLight.ttf b/public/fonts/saira-condensed/SairaCondensed-ExtraLight.ttf deleted file mode 100644 index e66b968d..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-ExtraLight.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-Light.ttf b/public/fonts/saira-condensed/SairaCondensed-Light.ttf deleted file mode 100644 index 59945aa1..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-Light.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-Medium.ttf b/public/fonts/saira-condensed/SairaCondensed-Medium.ttf deleted file mode 100644 index 12c99b4b..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-Medium.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-Regular.ttf b/public/fonts/saira-condensed/SairaCondensed-Regular.ttf deleted file mode 100644 index 61ee497b..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-Regular.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-SemiBold.ttf b/public/fonts/saira-condensed/SairaCondensed-SemiBold.ttf deleted file mode 100644 index 7def05e9..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-SemiBold.ttf and /dev/null differ diff --git a/public/fonts/saira-condensed/SairaCondensed-Thin.ttf b/public/fonts/saira-condensed/SairaCondensed-Thin.ttf deleted file mode 100644 index ae1ddf1b..00000000 Binary files a/public/fonts/saira-condensed/SairaCondensed-Thin.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Black.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-Black.ttf deleted file mode 100644 index 75da853a..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Black.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Bold.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-Bold.ttf deleted file mode 100644 index e5d68d4b..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Bold.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-ExtraBold.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-ExtraBold.ttf deleted file mode 100644 index f23a585f..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-ExtraBold.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-ExtraLight.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-ExtraLight.ttf deleted file mode 100644 index 06b8a69e..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-ExtraLight.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Light.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-Light.ttf deleted file mode 100644 index 1e084480..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Light.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Medium.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-Medium.ttf deleted file mode 100644 index 4805b4a8..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Medium.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Regular.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-Regular.ttf deleted file mode 100644 index dec98947..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Regular.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-SemiBold.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-SemiBold.ttf deleted file mode 100644 index 13638493..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-SemiBold.ttf and /dev/null differ diff --git a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Thin.ttf b/public/fonts/saira-extra-condensed/SairaExtraCondensed-Thin.ttf deleted file mode 100644 index ce461f7a..00000000 Binary files a/public/fonts/saira-extra-condensed/SairaExtraCondensed-Thin.ttf and /dev/null differ diff --git a/public/fonts/silkscreen/Silkscreen-Bold.ttf b/public/fonts/silkscreen/Silkscreen-Bold.ttf deleted file mode 100644 index df3b6830..00000000 Binary files a/public/fonts/silkscreen/Silkscreen-Bold.ttf and /dev/null differ diff --git a/public/fonts/silkscreen/Silkscreen-Regular.ttf b/public/fonts/silkscreen/Silkscreen-Regular.ttf deleted file mode 100644 index e087e178..00000000 Binary files a/public/fonts/silkscreen/Silkscreen-Regular.ttf and /dev/null differ diff --git a/public/icons/bolt.svg b/public/icons/bolt.svg deleted file mode 100644 index 33b8c107..00000000 --- a/public/icons/bolt.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/icons/browserconfig.xml b/public/icons/browserconfig.xml deleted file mode 100644 index 263173fc..00000000 --- a/public/icons/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #1B1916 - - - diff --git a/public/icons/database.svg b/public/icons/database.svg deleted file mode 100644 index af98bd5a..00000000 --- a/public/icons/database.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/icons/favicon.ico b/public/icons/favicon.ico deleted file mode 100644 index e9767fff..00000000 Binary files a/public/icons/favicon.ico and /dev/null differ diff --git a/public/icons/logo.svg b/public/icons/logo.svg deleted file mode 100644 index 701f8f6a..00000000 --- a/public/icons/logo.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/icons/microchip.svg b/public/icons/microchip.svg deleted file mode 100644 index f0c93ee0..00000000 --- a/public/icons/microchip.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/agent-logos/amp.svg b/public/images/agent-logos/amp.svg deleted file mode 100644 index c2dfe36a..00000000 --- a/public/images/agent-logos/amp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/agent-os/agentos-hero-logo.svg b/public/images/agent-os/agentos-hero-logo.svg deleted file mode 100644 index 52943354..00000000 --- a/public/images/agent-os/agentos-hero-logo.svg +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OS - - - - - diff --git a/public/images/frameworks/eve-icon.svg b/public/images/frameworks/eve-icon.svg deleted file mode 100644 index a55dfe67..00000000 --- a/public/images/frameworks/eve-icon.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/public/images/registry/amp.svg b/public/images/registry/amp.svg deleted file mode 100644 index 3820c275..00000000 --- a/public/images/registry/amp.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/images/registry/postgres.svg b/public/images/registry/postgres.svg deleted file mode 100644 index 8666f75c..00000000 --- a/public/images/registry/postgres.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/images/textures/bruegel-childrens-games-hero.jpg b/public/images/textures/bruegel-childrens-games-hero.jpg deleted file mode 100644 index ac91d459..00000000 Binary files a/public/images/textures/bruegel-childrens-games-hero.jpg and /dev/null differ diff --git a/public/images/textures/monet-water-lilies-hero.jpg b/public/images/textures/monet-water-lilies-hero.jpg deleted file mode 100644 index 0e9bc21c..00000000 Binary files a/public/images/textures/monet-water-lilies-hero.jpg and /dev/null differ diff --git a/public/images/textures/oil-olive-landscape.jpg b/public/images/textures/oil-olive-landscape.jpg deleted file mode 100644 index 40c10f21..00000000 Binary files a/public/images/textures/oil-olive-landscape.jpg and /dev/null differ diff --git a/src/components/GridPattern.jsx b/src/components/GridPattern.jsx deleted file mode 100644 index 8a28e7c1..00000000 --- a/src/components/GridPattern.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import backdrop from "@/images/effects/backdrop.svg"; - -export function GridPattern({ width, height, ...props }) { - // let patternId = useId(); - - return ( - - ); - // return ( - // - // ); -} diff --git a/src/components/Header.jsx b/src/components/Header.jsx deleted file mode 100644 index 50747d3f..00000000 --- a/src/components/Header.jsx +++ /dev/null @@ -1,334 +0,0 @@ -"use client"; -import { usePathname } from "@/hooks/usePathname"; -import { Popover, Transition } from "@headlessui/react"; -import clsx from "clsx"; -import { motion, useScroll, useTransform } from "framer-motion"; -import { forwardRef } from "react"; -import { Fragment } from "react"; - -import { Button } from "@/components/Button"; -import { - MobileNavigation, - useIsInsideMobileNavigation, -} from "@/components/MobileNavigation"; -import { useNavigation } from "@/hooks/useNavigation"; -import imgLogo from "@/images/rivet-logos/icon-cream.svg"; -import imgLogoText from "@/images/rivet-logos/icon-text-cream.svg"; -import { - Icon, - faCircle, - faDiamond, - faDiscord, - faFlask, - faGithub, - faHexagon, - faRhombus, - faSquare, -} from "@rivet-gg/icons"; - -const ICONS = { - godot: faHexagon, - unity: faSquare, - unreal: faCircle, - html5: faRhombus, - custom: faDiamond, -}; - -function TopLevelNavItem({ href, target, initHref, icon, children }) { - const pathname = usePathname(); - - const current = pathname?.startsWith(href); - return ( - - {icon ? : null} - {children} - - ); -} - -function TopLevelNavPopover({ solutions, callsToAction, children }) { - return ( - - - {children} - {/* - - - -
-
{solutions}
-
- {callsToAction} -
-
-
-
-
- ); -} - -function TopLevelNavPopoverSolution({ icon, href, title, description }) { - return ( -
-
-
-
- - {title} - - -

{description}

-
-
- ); -} - -function TopLevelNavPopoverCallToAction({ icon, href, title }) { - return ( - - - ); -} - -const StatusBadge = ({ status }) => { - if (status === "experimental") { - return ( - - - - ); - } -}; - -export const Header = forwardRef(function Header( - { className, tabsTitle, tabs }, - ref, -) { - const { navigation } = useNavigation(); - const pathname = usePathname(); - const isInsideMobileNavigation = useIsInsideMobileNavigation(); - - const { scrollY } = useScroll(); - const bgOpacityLight = useTransform(scrollY, [0, 72], [0.5, 0.9]); - const bgOpacityDark = useTransform(scrollY, [0, 72], [0.2, 0.8]); - - return ( - <> - - {/* Main header */} -
-
-
- -
- - - Rivet - - - - Rivet - - -
- - - Products - - - - - - - - - Documentation - - Changelog - - - Cloud - -
-
- -
- {/* Social icons */} - {/*
*/} - {[ - [faDiscord, "https://rivet.dev/discord"], - [faGithub, "https://github.com/rivet-dev"], - ].map(([icon, href]) => ( - - - - ))} - {/*
*/} - - {/* */} -
- -
-
-
- - {/* Tabs */} - {(navigation?.tabs || tabs) && ( -
- {/* Border */} -
- - -
- )} -
- - ); -}); diff --git a/src/components/Layout.jsx b/src/components/Layout.jsx deleted file mode 100644 index 6a2cc64e..00000000 --- a/src/components/Layout.jsx +++ /dev/null @@ -1,83 +0,0 @@ -import clsx from "clsx"; - -import { Feedback } from "@/components/Feedback"; -import { Footer, PageNextPrevious } from "@/components/Footer"; -import { HeroPattern } from "@/components/HeroPattern"; -import { Navigation } from "@/components/Navigation"; -import { Prose } from "@/components/Prose"; -import { TableOfContents } from "@/components/TableOfContents"; -import { Header } from "@/components/v2/Header"; - -export function Layout({ - navigation, - isTopPage, - fullWidth, - tableOfContents, - prose, - inset, - children, - sections = [], - pathname, -}) { - return ( -
-
- - {/* Body */} - {/*
*/} -
- {(prose || inset) && isTopPage ? : null} - -
- {navigation.sidebar ? ( - - ) : null} - -
- {prose ? ( - {children} - ) : ( - children - )} - - {navigation.feedback || navigation.sidebar ? ( -
- {navigation.sidebar ? ( - - ) : null} - {navigation.feedback ? : null} -
- ) : null} -
- - {/* Table of contents */} - -
- -
-
-
- ); -} diff --git a/src/components/MobileNavigation.jsx b/src/components/MobileNavigation.jsx deleted file mode 100644 index 4267aa13..00000000 --- a/src/components/MobileNavigation.jsx +++ /dev/null @@ -1,125 +0,0 @@ -import { Dialog, Transition } from "@headlessui/react"; -import clsx from "clsx"; -import { motion } from "framer-motion"; -import { Fragment, createContext, useContext } from "react"; -import { create } from "zustand"; - -import { Header } from "@/components/Header"; -import { Navigation } from "@/components/Navigation"; - -function MenuIcon(props) { - return ( - - ); -} - -function XIcon(props) { - return ( - - ); -} - -const IsInsideMobileNavigationContext = createContext(false); - -export function useIsInsideMobileNavigation() { - return useContext(IsInsideMobileNavigationContext); -} - -export const useMobileNavigationStore = create((set) => ({ - isOpen: false, - open: () => set({ isOpen: true }), - close: () => set({ isOpen: false }), - toggle: () => set((state) => ({ isOpen: !state.isOpen })), -})); - -export function MobileNavigation({ navigation }) { - const isInsideMobileNavigation = useIsInsideMobileNavigation(); - const { isOpen, toggle, close } = useMobileNavigationStore(); - const ToggleIcon = isOpen ? XIcon : MenuIcon; - - return ( - - - - {!isInsideMobileNavigation && ( - - - -
- - - - -
- - - - - - - - -
-
- )} -
- ); -} diff --git a/src/components/Navigation.jsx b/src/components/Navigation.jsx deleted file mode 100644 index 820e6d5d..00000000 --- a/src/components/Navigation.jsx +++ /dev/null @@ -1,141 +0,0 @@ -"use client"; -import { usePathname } from "@/hooks/usePathname"; -import routes from "@/generated/routes.json"; -import { faBooks, faCoin, faNewspaper } from "@rivet-gg/icons"; -import clsx from "clsx"; -import { motion } from "framer-motion"; - -import { Button } from "@/components/Button"; -import { useIsInsideMobileNavigation } from "@/components/MobileNavigation"; -import { ActiveSectionMarker } from "@/components/TableOfContents"; -import { Tag } from "@/components/Tag"; -import { normalizePath } from "@/lib/normalizePath"; - -function TopLevelNavItem({ href, target, children }) { - return ( -
  • - - {children} - -
  • - ); -} - -function NavLink({ href, tag, active, isAnchorLink = false, children }) { - return ( - - {children} - {tag && ( - - {tag} - - )} - - ); -} - -function NavigationGroup({ group, className }) { - // If this is the mobile navigation then we always render the initial - // state, so that the state does not change during the close animation. - // The state will still update when we re-open (re-render) the navigation. - const isInsideMobileNavigation = useIsInsideMobileNavigation(); - const pathname = usePathname(); - - return ( -
  • - - {group.title} - -
    - -
      - {group.pages.map((link) => { - const page = routes.pages[link.href]; - return ( - - {normalizePath(link.href) === normalizePath(pathname) ? ( - - ) : null} - - {page.title} - - - ); - })} -
    -
    -
  • - ); -} - -export function Navigation({ navigation, ...props }) { - const overviewGroup = { - title: "", - pages: [ - { title: "Overview", href: navigation.prefix }, - ...(navigation.pages ?? []), - ], - }; - - return ( - - ); -} diff --git a/src/components/Providers.jsx b/src/components/Providers.jsx index d0deb391..71fd2b56 100644 --- a/src/components/Providers.jsx +++ b/src/components/Providers.jsx @@ -1,8 +1,7 @@ "use client"; -import { useMobileNavigationStore } from "@/components/MobileNavigation"; import { NavigationStateProvider } from "@/providers/NavigationStateProvider"; import { Toaster, toast } from "@rivet-gg/components"; -import { Suspense, useEffect, useState } from "react"; +import { Suspense, useEffect } from "react"; function PageViewTracker() { useEffect(() => { @@ -22,14 +21,6 @@ function PageViewTracker() { return null; } -function RouteChangeObserver() { - useEffect(() => { - useMobileNavigationStore.getState().close(); - }, []); - - return null; -} - function CopyCodeListener() { useEffect(() => { const handleCopySuccess = () => { @@ -69,7 +60,6 @@ export function Providers({ children }) { - diff --git a/src/components/marketing/AnimatedAgentOSLogo.tsx b/src/components/marketing/AnimatedAgentOSLogo.tsx deleted file mode 100644 index d8f40386..00000000 --- a/src/components/marketing/AnimatedAgentOSLogo.tsx +++ /dev/null @@ -1,172 +0,0 @@ -'use client'; - -import { useEffect, useRef, useState } from 'react'; - -// Animated agentOS wordmark, ported from the agent-os site (AgentOSPage.tsx). -// Fetches the layered wordmark SVG and reveals the glyphs with a pen-draw mask. -// Keep the mask math in sync with the agent-os source when the asset changes. -interface AnimatedAgentOSLogoProps { - className?: string; - // Seconds for the main stroke-draw. Defaults to 3; pass a smaller value for - // a faster intro. - drawDurationSec?: number; -} - -export const AnimatedAgentOSLogo = ({ className, drawDurationSec = 3 }: AnimatedAgentOSLogoProps) => { - const containerRef = useRef(null); - const [isReady, setIsReady] = useState(false); - - useEffect(() => { - const container = containerRef.current; - if (!container) return; - - fetch('/images/agent-os/agentos-hero-logo-animated.svg') - .then((res) => res.text()) - .then((svgText) => { - container.innerHTML = svgText; - - const svg = container.querySelector('svg'); - if (!svg) return; - - svg.removeAttribute('width'); - svg.removeAttribute('height'); - svg.style.height = '100%'; - svg.style.width = 'auto'; - svg.style.display = 'block'; - - const ns = 'http://www.w3.org/2000/svg'; - const textLayer = svg.querySelector('#text-layer'); - const strokeLayer = svg.querySelector('#stroke-layer'); - if (!textLayer || !strokeLayer) return; - - const strokePath = strokeLayer.querySelector('path'); - if (!strokePath) return; - - // The wordmark reveals the real glyphs through a mask that follows - // the pen path, so the finished logo is the brand mark itself and - // nothing settles or swaps after the pen stops. Three strokes per - // subpath keep the reveal honest at self-intersections: a wide white - // stroke reveals the written portion, a black stroke over the - // unwritten remainder conceals ink the pen has not reached yet (the - // hanging edges at crossings), and a narrower white stroke on top - // restores the written line where the unwritten portion crosses it. - // pathLength=100 normalizes the dash math so one keyframe pair - // serves every stroke regardless of geometric length. - const fullD = strokePath.getAttribute('d') || ''; - const lastM = fullD.lastIndexOf('M'); - const mainD = fullD.substring(0, lastM); - const tailD = fullD.substring(lastM); - - const defs = document.createElementNS(ns, 'defs'); - svg.insertBefore(defs, svg.firstChild); - const mask = document.createElementNS(ns, 'mask'); - mask.setAttribute('id', 'agentos-reveal-mask'); - mask.setAttribute('maskUnits', 'userSpaceOnUse'); - mask.setAttribute('x', '0'); - mask.setAttribute('y', '0'); - mask.setAttribute('width', '99999'); - mask.setAttribute('height', '99999'); - const groupTransform = strokeLayer.getAttribute('transform') || ''; - const makeMaskStroke = (d: string, color: string, width: number, cap: string) => { - const group = document.createElementNS(ns, 'g'); - group.setAttribute('transform', groupTransform); - const path = document.createElementNS(ns, 'path'); - path.setAttribute('d', d); - path.setAttribute('pathLength', '100'); - path.setAttribute( - 'style', - `fill:none; stroke:${color}; stroke-width:${width}px; stroke-linecap:${cap}; stroke-linejoin:round;`, - ); - // The gap exceeds the dash by 1 so no offset ever lands a - // zero-length dash on the path end. With round caps that - // degenerate dash renders as a floating dot. - path.style.strokeDasharray = '100 101'; - group.appendChild(path); - mask.appendChild(group); - return path; - }; - // Paint order matters: reveal below, conceal above it, restore on top. - // The conceal stroke uses butt caps so it ends exactly at the pen tip - // instead of eating half a cap backwards into fresh ink. The restore - // stroke is only a hair wider than the letterform (~6.8 in this - // space): any wider and it re-reveals concealed ink where an - // unwritten stroke crosses a written one. - const reveals = [makeMaskStroke(mainD, 'white', 10.57, 'round'), makeMaskStroke(tailD, 'white', 10.57, 'round')]; - const conceals = [makeMaskStroke(mainD, 'black', 10.57, 'butt'), makeMaskStroke(tailD, 'black', 10.57, 'butt')]; - const restores = [makeMaskStroke(mainD, 'white', 7.6, 'round'), makeMaskStroke(tailD, 'white', 7.6, 'round')]; - defs.appendChild(mask); - - // Wrap the text layer in a masked group. - const textParent = textLayer.parentNode; - if (textParent) { - const wrapper = document.createElementNS(ns, 'g'); - wrapper.setAttribute('mask', 'url(#agentos-reveal-mask)'); - textParent.insertBefore(wrapper, textLayer); - wrapper.appendChild(textLayer); - } - strokeLayer.remove(); - - // Animate like a real pen. The word must keep drawing at near-constant - // speed to the end: an ease-out crawl leaves the "t" sitting uncrossed - // and half-drawn for the last second of the animation. The crossbar - // follows after a brief pen lift as a quick flick. - const mainDuration = drawDurationSec; - const penLift = 0.09; - const tailDuration = 0.16; - - if (!document.querySelector('#agentos-logo-animation-style')) { - const style = document.createElement('style'); - style.id = 'agentos-logo-animation-style'; - style.textContent = ` - @keyframes agentos-draw { - to { stroke-dashoffset: 0; } - } - @keyframes agentos-conceal { - to { stroke-dashoffset: -100; } - } - `; - document.head.appendChild(style); - } - - if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { - // Static: mask fully open, filled glyphs shown immediately. - for (const path of [...reveals, ...restores]) path.style.strokeDashoffset = '0'; - for (const path of conceals) path.style.strokeDashoffset = '-100'; - } else { - const timings = [ - `${mainDuration}s cubic-bezier(0.3, 0, 0.75, 0.85) 0s`, - `${tailDuration}s cubic-bezier(0.3, 0, 0.6, 1) ${mainDuration + penLift}s`, - ]; - [reveals, restores].forEach((pair) => - pair.forEach((path, i) => { - path.style.strokeDashoffset = '100.5'; - path.style.animation = `agentos-draw ${timings[i]} forwards`; - }), - ); - conceals.forEach((path, i) => { - path.style.strokeDashoffset = '0'; - path.style.animation = `agentos-conceal ${timings[i]} forwards`; - }); - } - - setIsReady(true); - }); - - return () => { - if (container) { - container.innerHTML = ''; - } - }; - }, [drawDurationSec]); - - return ( -
    - ); -}; diff --git a/src/components/marketing/ClosingCtaPanel.tsx b/src/components/marketing/ClosingCtaPanel.tsx index 0c826d9e..f490f06f 100644 --- a/src/components/marketing/ClosingCtaPanel.tsx +++ b/src/components/marketing/ClosingCtaPanel.tsx @@ -15,8 +15,6 @@ interface ClosingCtaPanelProps { children?: ReactNode; /** Quiet line under the buttons (e.g. a "Questions? Contact us" aside). */ footnote?: ReactNode; - /** Slot into the page's paper / paper-mid section alternation. */ - background?: 'paper' | 'paper-mid'; /** Oil-painting backdrop for the colophon; omit for the flat ink plate. */ textureSrc?: string; /** Set false to show the texture without the darkening veil. */ diff --git a/src/components/marketing/CopyInstallCommand.tsx b/src/components/marketing/CopyInstallCommand.tsx new file mode 100644 index 00000000..64adbfe8 --- /dev/null +++ b/src/components/marketing/CopyInstallCommand.tsx @@ -0,0 +1,33 @@ +"use client"; + +import { useState } from "react"; + +export function CopyInstallCommand({ command }: { command: string }) { + const [copied, setCopied] = useState(false); + + const handleCopy = async () => { + await navigator.clipboard.writeText(command); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }; + + return ( + + ); +} diff --git a/src/components/marketing/ProductHero.tsx b/src/components/marketing/ProductHero.tsx deleted file mode 100644 index 36699ffd..00000000 --- a/src/components/marketing/ProductHero.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { ProductLockup } from "./ProductLockup"; -import { getProduct } from "@/sitemap/products"; -import { - PRODUCT_HERO_CTA_ROW_CLASS, - PRODUCT_HERO_H1_CLASS, - PRODUCT_HERO_INNER_CLASS, - PRODUCT_HERO_PRIMARY_BUTTON_CLASS, - PRODUCT_HERO_SECONDARY_BUTTON_CLASS, - PRODUCT_HERO_SECTION_CLASS, - PRODUCT_HERO_SUBTITLE_CLASS, -} from "./typography"; - -/** - * The shared product hero: mark, title, subtitle, CTA pair. - * - * Modelled on the agentOS hero, which leads with the logo and lets the headline - * make a claim. The product's *name* lives in the mark, so the title should say - * something rather than repeat it. - */ -export function ProductHero({ - productId, - title, - subtitle, - docsHref, -}: { - productId: string; - /** Defaults to the product's tagline, the same line the switcher shows. */ - title?: string; - subtitle: string; - docsHref: string; -}) { - const product = getProduct(productId); - const heading = title ?? product?.description ?? ""; - - return ( -
    -
    - {product && ( -
    - -
    - )} - -

    - {heading} -

    - -

    - {subtitle} -

    - - -
    -
    - ); -} diff --git a/src/components/marketing/ProductHeroCta.tsx b/src/components/marketing/ProductHeroCta.tsx deleted file mode 100644 index 923e5706..00000000 --- a/src/components/marketing/ProductHeroCta.tsx +++ /dev/null @@ -1,82 +0,0 @@ -"use client"; - -import { useState } from "react"; -import { - PRODUCT_HERO_CTA_ROW_CLASS, - PRODUCT_HERO_PRIMARY_BUTTON_CLASS, -} from "./typography"; - -/** - * The hero CTA pair, lifted from the agentOS hero so every product hero is - * visually identical: an install chip that copies itself, and a filled button - * that sends you into the product's setup. - * - * The styling is copied verbatim from `AgentOSPage`'s `CopyInstallCommand` and - * `SetupWithAgent`. Change it here and change it there, or better, move agentOS - * onto this component too. - */ -export function CopyInstallCommand({ command }: { command: string }) { - const [copied, setCopied] = useState(false); - - const handleCopy = async () => { - await navigator.clipboard.writeText(command); - setCopied(true); - setTimeout(() => setCopied(false), 2000); - }; - - return ( - - ); -} - -/** The filled companion to the install chip. Same styling as `SetupWithAgent`. */ -export function SetupProjectButton({ - href, - label = "Set up project", -}: { - href: string; - label?: string; -}) { - return ( - - {label} - - ); -} - -/** The row itself, so spacing matches the agentOS hero exactly. */ -export function ProductHeroCta({ - command, - setupHref, - setupLabel, -}: { - command: string; - setupHref: string; - setupLabel?: string; -}) { - return ( -
    - - -
    - ); -} diff --git a/src/components/marketing/agentos/AgentOSPage.tsx b/src/components/marketing/agentos/AgentOSPage.tsx index 1fb0fbcc..34c8f7b2 100644 --- a/src/components/marketing/agentos/AgentOSPage.tsx +++ b/src/components/marketing/agentos/AgentOSPage.tsx @@ -1,11 +1,10 @@ 'use client'; -import { useId, useState, useEffect, useRef, useCallback, useMemo } from 'react'; +import { useId, useState, useEffect, useRef, useCallback } from 'react'; import { ArrowRight, Layers, Wrench, - ExternalLink, Activity, HardDrive, Users, @@ -26,8 +25,6 @@ import { CalendarClock, Gauge, AppWindow, - Database, - Rocket, } from 'lucide-react'; import { AnimatePresence, motion, useReducedMotion } from 'framer-motion'; import actorsLogoUrl from '@/images/products/actors-logo.svg'; @@ -36,8 +33,16 @@ import { wordmarkMaskStyle } from '@/lib/product-accent'; import { registry } from '@/data/registry'; import { REGISTRY_ICONS } from '@/data/registry-icons'; import { AGENT_PROMPT } from '@/data/agentPrompt'; +import { + benchColdStart, + benchWorkloads, + BENCHMARK_DATE, + SANDBOX_COLDSTART_PROVIDER, + SANDBOX_COST_PROVIDER, + sandboxCostPerSec, +} from '@/data/bench'; import { DeploymentOptions } from '@/components/marketing/DeploymentOptions'; -import { CopyInstallCommand } from '@/components/marketing/ProductHeroCta'; +import { CopyInstallCommand } from '@/components/marketing/CopyInstallCommand'; import { ClosingCtaPanel } from '@/components/marketing/ClosingCtaPanel'; import { SectionRule } from '@/components/marketing/SectionRule'; import { @@ -54,23 +59,15 @@ import { SECTION_H2_CLASS, SECTION_LEDE_CENTERED_CLASS, SECTION_LEDE_CLASS, - SectionHeading, } from '@/components/marketing/typography'; import { SITE_CARD_CLASS, SITE_SECTION_CLASS, SITE_STANDARD_RAIL_CLASS, } from '@/components/marketing/layout'; -import { ColdStartTimeline } from '@/components/marketing/diagrams/ColdStartTimeline'; import { AgentSessionDemo } from '@/components/marketing/diagrams/AgentSessionDemo'; -import { AgentOsTopologyCell, SandboxTopologyCell } from '@/components/marketing/diagrams/TopologyCells'; import { Reveal } from '@/components/marketing/motion'; -// Porcelain card surface shared by the architecture cards and feature bento: -// a flat translucent fill and hairline ring, with no drop shadow. -const CARD_SURFACE = - 'rounded-xl border border-ink/10 bg-white/55 ' + 'transition-[background-color,border-color] duration-300 ' + 'hover:border-ink/15 hover:bg-white ' + 'motion-reduce:transition-none'; - interface HeroTabCode { key: string; fileName: string; @@ -1477,383 +1474,6 @@ const RegistrySection = () => { ); }; -// --- Benchmarks --- -// Benchmark data (computed from raw inputs in bench.ts) -import { benchColdStart, benchWorkloads, BENCHMARK_DATE, SANDBOX_COLDSTART_PROVIDER, SANDBOX_COST_PROVIDER, sandboxCostPerSec, type WorkloadKey } from '@/data/bench'; - -function BenchInfoTooltip({ children }: { children: React.ReactNode }) { - // Anchored to the icon itself: the wrapper is positioned and the tooltip - // opens directly above it. The pb-2 gap lives inside the hover target so - // the pointer can travel from icon to tooltip (for the links) without a - // dead zone. The tooltip stays an ink plate — the site's surface for data - // asides — floating over the light card. - return ( - - - - - - - {children} - - - - ); -} - -// Pill options in the card's caption bar, reusing the site's rounded-full -// ring pill (carousel chevrons, the cards' ? buttons); the active option is -// filled ink like the primary buttons. -function BenchToggle({ options, active, onChange }: { options: string[]; active: number; onChange: (idx: number) => void }) { - return ( -
    - {options.map((label, i) => { - const isActive = i === active; - return ( - - ); - })} -
    - ); -} - -interface BenchRowEntry { - label: React.ReactNode; - value: string; - highlight?: boolean; -} - -// Splits a stat string into a leading symbol prefix, the numeric portion, and a -// trailing unit suffix so the number can be counted up while the units stay put. -// Returns null when there is no number to animate (e.g. "Infinite"). -function parseStatNumber(text: string) { - const match = text.match(/^([^\d-]*)(-?[\d,]*\.?\d+)(.*)$/); - if (!match) return null; - const [, prefix, rawNumber, suffix] = match; - const normalized = rawNumber.replace(/,/g, ''); - const decimals = normalized.includes('.') ? normalized.split('.')[1].length : 0; - return { - prefix, - suffix, - value: Number.parseFloat(normalized), - decimals, - grouped: rawNumber.includes(','), - }; -} - -// Counts the numeric part of a stat from 0 up to its value. The first run is -// gated on `active` (the card scrolling into view) and only fires once; later -// value changes (toggling workload or tier) re-trigger the count from the -// previous value. Honors reduced-motion by rendering the final value outright. -function CountUpStat({ text, active }: { text: string; active: boolean }) { - const parsed = useMemo(() => parseStatNumber(text), [text]); - const reducedMotion = useReducedMotion(); - const target = parsed?.value ?? 0; - - const [display, setDisplay] = useState(0); - const startedRef = useRef(false); - const fromRef = useRef(0); - const rafRef = useRef(0); - - useEffect(() => { - if (!parsed) return; - if (reducedMotion) { - setDisplay(target); - fromRef.current = target; - startedRef.current = true; - return; - } - // Not yet scrolled into view: stay primed at zero for the first count-up. - if (!active) { - if (!startedRef.current) setDisplay(0); - return; - } - const from = startedRef.current ? fromRef.current : 0; - startedRef.current = true; - const duration = 850; - let start = 0; - const step = (now: number) => { - if (!start) start = now; - const t = Math.min(1, (now - start) / duration); - const eased = 1 - (1 - t) ** 3; - setDisplay(from + (target - from) * eased); - if (t < 1) { - rafRef.current = requestAnimationFrame(step); - } else { - fromRef.current = target; - } - }; - rafRef.current = requestAnimationFrame(step); - return () => cancelAnimationFrame(rafRef.current); - }, [parsed, target, active, reducedMotion]); - - if (!parsed) return <>{text}; - - const formatted = parsed.grouped - ? display.toLocaleString(undefined, { - minimumFractionDigits: parsed.decimals, - maximumFractionDigits: parsed.decimals, - }) - : display.toFixed(parsed.decimals); - - return ( - - {parsed.prefix} - {formatted} - {parsed.suffix} - - ); -} - -// Light data card on the site's card surface: title, headline multiplier, -// comparison rows, and an optional tier toggle in the caption bar. The -// agentOS row carries pine, matching the ledger's "agentOS" column above. -function BenchCard({ - title, - statNote, - verb, - toggle, - rows, - note, - onHelp, - helpLabel, - helpTip, -}: { - title: string; - statNote: string; - verb: string; - toggle?: React.ReactNode; - rows: BenchRowEntry[]; - note?: string; - onHelp?: () => void; - helpLabel?: string; - helpTip?: React.ReactNode; -}) { - // Trigger the count-up the first time the card scrolls into view, once. - const [inView, setInView] = useState(false); - - return ( - setInView(true)} viewport={{ once: true, margin: '-10% 0px' }}> -
    - {title} - {onHelp ? ( - - ) : helpTip ? ( - // Anchored under the ? itself, opening down-left from the card corner. - - - ? - - - {helpTip} - - - ) : null} -
    - - {/* Verdict: the headline multiplier */} -
    - - - - {verb} -
    - - {/* Comparison ledger: ours vs theirs, same unit, right-aligned */} -
    - {rows.map((row, i) => ( -
    - {row.label} - {row.value} -
    - ))} -
    - - {/* Caption bar flush with the card foot: holds the tier options or a - one-line measurement note. */} - {toggle || note ? ( -
    {toggle ?? note}
    - ) : null} -
    - ); -} - -function BenchColdStartChart({ onHelp }: { onHelp?: () => void }) { - const groups = benchColdStart; - // Default to p50 so the hero chip's claim and this card's first-shown number agree. - const [active, setActive] = useState(0); - const g = groups[active]; - - return ( - t.label)} active={active} onChange={setActive} />} - rows={[ - { - label: ( - <> - agentOS - - What's measured: Time from requesting an execution to first code running. -
    -
    - Why the gap: agentOS runs agents in-process — WASM inside your host. No VM to boot, no network hop, no disk image. Sandboxes must boot an entire environment, allocate - memory, and establish a network connection before code can run. -
    -
    - Sandbox baseline: {SANDBOX_COLDSTART_PROVIDER}, the fastest mainstream sandbox provider as of {BENCHMARK_DATE}. -
    -
    - agentOS: Median of 10,000 runs (100 iterations x 100 samples) on Intel i7-12700KF. -
    - - ), - value: `${g.agentOS} ms`, - highlight: true, - }, - { label: 'Fastest sandbox', value: `${g.sandbox.toLocaleString()} ms` }, - ]} - /> - ); -} - -function BenchMemoryBar({ workload }: { workload: WorkloadKey }) { - const mem = benchWorkloads[workload].memory; - const [memMult, memVerb] = mem.multiplier.split(' '); - - return ( - - agentOS - - What's measured: Memory footprint added per concurrent execution. -
    -
    - Why the gap: In-process isolates share the host's memory. Each additional execution only adds its own heap and stack. Sandboxes allocate a dedicated environment with a - minimum memory reservation, even if the code inside uses far less. -
    -
    - Sandbox baseline: {SANDBOX_COST_PROVIDER}, the cheapest mainstream sandbox provider as of {BENCHMARK_DATE}. Default sandbox: 1 vCPU + 1 GiB RAM. -
    -
    - agentOS:{' '} - {workload === 'agent' - ? `${benchWorkloads.agent.memory.agentOS} for a full Pi coding agent session with MCP servers and file system mounts.` - : `${benchWorkloads.shell.memory.agentOS} for the minimal shell workload under sustained load.`} -
    - - ), - value: mem.agentOS, - highlight: true, - }, - { label: 'Cheapest sandbox', value: mem.sandbox }, - ]} - helpTip='Sandboxes reserve idle RAM per agent.' - /> - ); -} - -function BenchCostChart({ workload }: { workload: WorkloadKey }) { - const tiers = benchWorkloads[workload].cost; - const sandboxCost = benchWorkloads[workload].sandboxCost; - // Default to AWS ARM so the hero chip's claim and this card's first-shown number agree. - const [active, setActive] = useState(() => - Math.max( - 0, - tiers.findIndex((tier) => tier.label === 'AWS ARM'), - ), - ); - const t = tiers[active]; - const [costMult, costVerb] = t.multiplier.split(' '); - - return ( - tier.label)} active={active} onChange={setActive} />} - rows={[ - { - label: ( - <> - agentOS - - What's measured: server price per second / concurrent executions per server -
    -
    - Why it's cheaper: Each execution uses {benchWorkloads[workload].memory.agentOS} instead of a {benchWorkloads[workload].memory.sandbox} sandbox minimum. And you - run on your own hardware, which is significantly cheaper than per-second sandbox billing. -
    -
    - Sandbox baseline: {SANDBOX_COST_PROVIDER}, the cheapest mainstream sandbox provider as of {BENCHMARK_DATE}. Default sandbox: 1 vCPU + 1 GiB RAM at $0.0504/vCPU-h + - $0.0162/GiB-h. -
    -
    - agentOS: {benchWorkloads[workload].memory.agentOS} baseline per execution, assuming 70% utilization (industry-standard HPA scaling threshold). Select a hardware tier - above to compare. -
    - - ), - value: t.value, - highlight: true, - }, - { label: 'Cheapest sandbox', value: sandboxCost }, - ]} - helpTip='Assumes one agent per sandbox, needed for isolation.' - /> - ); -} - -function BenchmarkSection({ onShowColdStart }: { onShowColdStart?: () => void }) { - // Single measured workload; the coding-agent variant lives on in bench.ts - // data but is not surfaced here. - const workload: WorkloadKey = 'shell'; - - return ( - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    - ); -} - // --- Floating foundation map --- // Execution, filesystem, and orchestration split evenly across the section. // The bubbles name recognizable integrations and patterns without turning the @@ -2725,116 +2345,6 @@ const SecondaryFeaturesSection = () => ( ); -// --- Argument (why a library, not a sandbox service) --- -// The topology makes the architectural contrast first; the benchmark block -// below provides the measured proof for startup, memory, and cost. - -// Modal wrapper for the cold-start timeline, opened from the benchmarks -// header. Mounting the timeline on open replays its sequence each time. -const ColdStartModal = ({ open, onClose }: { open: boolean; onClose: () => void }) => { - useEffect(() => { - if (!open) return; - const onKey = (e: KeyboardEvent) => e.key === 'Escape' && onClose(); - document.addEventListener('keydown', onKey); - const prevOverflow = document.body.style.overflow; - document.body.style.overflow = 'hidden'; - return () => { - document.removeEventListener('keydown', onKey); - document.body.style.overflow = prevOverflow; - }; - }, [open, onClose]); - - return ( - - {open && ( - - e.stopPropagation()} - className='relative max-h-full w-full max-w-3xl overflow-y-auto rounded-2xl bg-paper p-6 shadow-[0_24px_70px_-20px_rgba(20,20,22,0.45)] ring-1 ring-ink/10 md:p-9' - > - - - - )} - - ); -}; - -const ComparisonSection = () => ( -
    -
    - - - An isolated OS for every agent. -
    - Much lighter than a full sandbox VM. - - } - subtitle='Per-agent isolation without duplicating a complete VM stack for every agent.' - className='mb-10 max-w-3xl md:mb-12' - /> -
    - - {/* Complete VM stacks versus compact isolated OS instances. */} - -
    -
    -
    -

    Full sandbox per agent

    - -
    -
    -

    Isolated OS per agent

    - -
    -
    -
    -
    -
    -
    -); - -const BenchmarksSection = () => { - const [showColdStart, setShowColdStart] = useState(false); - - return ( - <> -
    -
    - -
    -

    What staying in-process saves.

    - - Benchmark document - - -
    -
    - setShowColdStart(true)} /> -
    -
    - - setShowColdStart(false)} /> - - ); -}; - // --- Deployment --- // The same Local -> Rivet Cloud -> Self-Host decision used by the homepage and // Workflows page. @@ -2875,7 +2385,7 @@ const DeploymentSection = () => { // The page opens with the argument (an OS, not a sandbox) and closes with the // action. Repeats the hero CTAs so the reader never scrolls back up to act. const ClosingCta = () => ( - + Read the Docs diff --git a/src/components/marketing/agentos/AgentOSUseCasesPage.tsx b/src/components/marketing/agentos/AgentOSUseCasesPage.tsx deleted file mode 100644 index d6ef3c8e..00000000 --- a/src/components/marketing/agentos/AgentOSUseCasesPage.tsx +++ /dev/null @@ -1,254 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import { motion } from 'framer-motion'; -import { - ArrowRight, - Clock, - FlaskConical, - Code, - User, - Users, - Database, - Workflow, - Check, - Copy, -} from 'lucide-react'; -import { - HERO_H1_CLASS, - PRIMARY_INK_BUTTON_CLASS, - PRODUCT_HERO_SECONDARY_BUTTON_CLASS, - SECTION_H2_CLASS, -} from '@/components/marketing/typography'; -import { SectionRule } from '@/components/marketing/SectionRule'; -import { AGENT_PROMPT } from '@/data/agentPrompt'; - -// --- Copy Agent Prompt Button --- -const CopyAgentPromptButton = () => { - const [copied, setCopied] = useState(false); - - const handleCopy = async () => { - try { - await navigator.clipboard.writeText(AGENT_PROMPT); - setCopied(true); - setTimeout(() => setCopied(false), 2000); - } catch (err) { - console.error('Failed to copy:', err); - } - }; - - return ( - - ); -}; - -interface UseCaseProps { - icon: React.ComponentType<{ className?: string }>; - title: string; - description: string; - benefits: string[]; - example?: string; - delay?: number; -} - -const UseCase = ({ icon: Icon, title, description, benefits, example, delay = 0 }: UseCaseProps) => ( - -
    - -
    -

    {title}

    -

    {description}

    -
      - {benefits.map((benefit, i) => ( -
    • - - {benefit} -
    • - ))} -
    - {example && ( -
    - Example -

    {example}

    -
    - )} -
    -); - -export const useCases: UseCaseProps[] = [ - { - icon: Code, - title: 'Programming Agents', - description: 'Purpose-built for agents that write, test, and deploy code autonomously.', - benefits: [ - 'Native file system access with git support', - 'Shell execution with full toolchain access', - 'Package installation and dependency management', - 'Test runner integration', - ], - example: 'An agent that takes a GitHub issue, writes the fix, runs tests, and opens a pull request.', - }, - { - icon: Clock, - title: 'Background Agents', - description: 'Long-running agents that operate asynchronously, processing tasks over hours or days without human intervention.', - benefits: [ - 'Persistent state survives crashes and restarts', - 'Queue commands while agents work', - 'Resume from exactly where they left off', - 'Monitor progress in real-time', - ], - example: 'A code migration agent that refactors a large codebase over several hours, committing changes incrementally.', - }, - { - icon: FlaskConical, - title: 'Evals', - description: 'Run agent evaluations and benchmarks at scale without spinning up expensive sandboxes for each test.', - benefits: [ - 'Low memory per instance compared to sandboxes', - 'Near-zero cold starts for rapid iteration', - 'Deterministic replay for debugging', - 'Parallel runs on independently addressed Actors', - ], - example: 'Evaluating agent responses in parallel to compare performance across prompts.', - }, - { - icon: Users, - title: 'Multi-Agent Systems', - description: 'Coordinate multiple agents working together on complex tasks with shared state and communication.', - benefits: [ - 'Shared file systems between agents', - 'Real-time inter-agent messaging', - 'Optional durable Workflows layer', - 'Centralized observability', - ], - example: 'A team of agents where one researches, one writes, and one reviews, all collaborating on a document.', - }, - { - icon: Database, - title: 'Data Processing', - description: 'Run ETL pipelines, data transformations, and analysis tasks with agent intelligence.', - benefits: [ - 'Stream processing capabilities', - 'Database connections and queries', - 'File format conversion', - 'Incremental processing', - ], - example: 'An agent that ingests raw data, cleans it, runs analysis, and generates reports on a schedule.', - }, - { - icon: Workflow, - title: 'Workflow Automation', - description: 'Chain agent tasks into complex workflows with conditional logic and human-in-the-loop steps.', - benefits: [ - 'Durable workflow execution', - 'Retry and error handling', - 'Scheduled and triggered runs', - 'Approval gates and notifications', - ], - example: 'A hiring workflow where agents screen resumes, schedule interviews, and prepare onboarding docs.', - }, - { - icon: User, - title: 'Personal Agents', - description: 'Lightweight agents that assist individual users with daily tasks and workflows.', - benefits: [ - 'Low resource overhead for personal use', - 'Local-first with optional cloud sync', - 'Custom tool integration', - 'Privacy-focused execution', - ], - example: 'A personal agent that organizes your calendar, drafts emails, and manages your todo list.', - }, -]; - -export default function AgentOSUseCasesPage() { - return ( -
    - ); -} diff --git a/src/components/marketing/art/PixelGridChart.tsx b/src/components/marketing/art/PixelGridChart.tsx deleted file mode 100644 index 8894029a..00000000 --- a/src/components/marketing/art/PixelGridChart.tsx +++ /dev/null @@ -1,88 +0,0 @@ -'use client'; - -import { motion, useReducedMotion } from 'framer-motion'; - -// Pixel-grid bar chart for dark data cards: each column is a stack of rounded -// square cells filled bottom-up. Designed to live inside an InkPanel; filled -// cells are warm white with an optional sage accent column. Animates a -// bottom-up stagger fill on scroll into view, or renders static when the -// user prefers reduced motion or `animate` is false. - -interface PixelGridChartProps { - values: number[]; - rows?: number; - cell?: number; - gap?: number; - accentColumn?: number; - accentColor?: string; - animate?: boolean; - className?: string; -} - -export const PixelGridChart = ({ - values, - rows = 11, - cell = 13, - gap = 5, - accentColumn, - accentColor = '#93A286', - animate = true, - className, -}: PixelGridChartProps) => { - const reducedMotion = useReducedMotion(); - const animated = animate && !reducedMotion; - - const width = values.length * (cell + gap) - gap; - const height = rows * (cell + gap) - gap; - const radius = cell * 0.22; - - const cells: Array<{ x: number; y: number; fill: string; delay: number }> = []; - values.forEach((value, col) => { - const filled = Math.round(Math.max(0, Math.min(1, value)) * rows); - for (let row = 0; row < rows; row++) { - const isFilled = row < filled; - cells.push({ - x: col * (cell + gap), - y: height - (row + 1) * (cell + gap) + gap, - fill: isFilled - ? col === accentColumn - ? accentColor - : '#F4EFE6' - : 'rgba(244, 239, 230, 0.07)', - // Filled cells stagger in by column then row; empty cells are static. - delay: isFilled ? col * 0.05 + row * 0.02 : 0, - }); - } - }); - - return ( - - ); -}; diff --git a/src/components/marketing/art/Spirograph.tsx b/src/components/marketing/art/Spirograph.tsx deleted file mode 100644 index 91c5bdf0..00000000 --- a/src/components/marketing/art/Spirograph.tsx +++ /dev/null @@ -1,134 +0,0 @@ -// Deterministic hypotrochoid rosette rendered as static SVG. One closed path -// is defined once and stamped as rotated copies; the moiré interference -// comes from the rotation offsets, so the markup stays small. SSR-safe, no -// hooks, no canvas. -// -// x(t) = (R - r)·cos t + d·cos(((R - r)/r)·t) -// y(t) = (R - r)·sin t - d·sin(((R - r)/r)·t) -// -// With integer R and r the curve closes after r / gcd(R, r) revolutions. - -interface SpirographProps { - variant?: 'moire' | 'rosette' | 'ring'; - R?: number; - r?: number; - d?: number; - copies?: number; - size?: number; - stroke?: string; - strokeWidth?: number; - strokeOpacity?: number; - seed?: number; - rotate?: boolean; - className?: string; -} - -const PRESETS: Record = { - moire: { R: 120, r: 36, d: 84, copies: 48 }, - rosette: { R: 144, r: 60, d: 100, copies: 24 }, - ring: { R: 210, r: 66, d: 90, copies: 3 }, -}; - -const gcd = (a: number, b: number): number => (b ? gcd(b, a % b) : a); - -// Small deterministic PRNG so seeded jitter is stable across SSR and client. -const mulberry32 = (seed: number) => { - let a = seed >>> 0; - return () => { - a |= 0; - a = (a + 0x6d2b79f5) | 0; - let t = Math.imul(a ^ (a >>> 15), 1 | a); - t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; - return ((t ^ (t >>> 14)) >>> 0) / 4294967296; - }; -}; - -const hypotrochoidPath = (R: number, r: number, d: number): string => { - const revolutions = r / gcd(Math.round(R), Math.round(r)); - const maxT = revolutions * 2 * Math.PI; - const step = 0.05; - const points: string[] = []; - for (let t = 0; t <= maxT + step; t += step) { - const x = (R - r) * Math.cos(t) + d * Math.cos(((R - r) / r) * t); - const y = (R - r) * Math.sin(t) - d * Math.sin(((R - r) / r) * t); - points.push(`${x.toFixed(1)},${y.toFixed(1)}`); - } - return `M${points.join('L')}Z`; -}; - -export const Spirograph = ({ - variant = 'ring', - R, - r, - d, - copies, - size = 480, - stroke = '#5A6B52', - strokeWidth = 0.7, - strokeOpacity = 0.45, - seed = 0, - rotate = false, - className, -}: SpirographProps) => { - const preset = PRESETS[variant]; - const pR = R ?? preset.R; - const pr = r ?? preset.r; - const pd = d ?? preset.d; - const pCopies = copies ?? preset.copies; - - // Id derived from the curve parameters: stable across SSR and hydration, - // and identical instances may safely share a def. - const id = `spiro-${pR}-${pr}-${pd}-${pCopies}-${stroke.replace(/[^a-zA-Z0-9]/g, '')}`; - - const rand = seed ? mulberry32(seed) : null; - const paths: string[] = []; - if (rand) { - // Seeded mode jitters d per copy for an organic, hand-drawn moiré. - for (let k = 0; k < pCopies; k++) { - paths.push(hypotrochoidPath(pR, pr, pd + (rand() - 0.5) * 8)); - } - } else { - paths.push(hypotrochoidPath(pR, pr, pd)); - } - - return ( - - ); -}; diff --git a/src/components/marketing/bench/BenchCard.tsx b/src/components/marketing/bench/BenchCard.tsx deleted file mode 100644 index ff2f8321..00000000 --- a/src/components/marketing/bench/BenchCard.tsx +++ /dev/null @@ -1,215 +0,0 @@ -'use client'; - -// Benchmark card primitives: the light data card with a sans eyebrow, a -// count-up headline, a comparison ledger, an optional toggle, and floating info -// tooltips. Used by the Actors marketing page (Actors vs. traditional -// infrastructure). - -import { useId, useMemo, useState, useRef, useEffect } from 'react'; -import type { ReactNode } from 'react'; -import { motion, useReducedMotion } from 'framer-motion'; - -export function BenchInfoTooltip({ children }: { children: ReactNode }) { - // The wrapper is intentionally not positioned so the tooltip spans the - // card itself (the nearest positioned ancestor) instead of clipping at the - // panel's overflow-hidden edge. - return ( - - - - - - {children} - - - ); -} - -export function BenchToggle({ options, active, onChange }: { options: string[]; active: number; onChange: (idx: number) => void }) { - const layoutId = useId(); - const columns = options.length === 3 ? 'grid-cols-3' : options.length === 4 ? 'grid-cols-2' : 'grid-cols-2'; - - return ( -
    - {options.map((label, i) => { - const isActive = i === active; - return ( - onChange(i)} - aria-pressed={isActive} - whileTap={{ scale: 0.94 }} - className={`relative flex h-7 min-w-0 items-center justify-center rounded-md px-1.5 text-center text-xs font-medium transition-colors ${ - isActive ? 'text-cream' : 'text-ink-faint hover:text-ink' - }`} - > - {isActive && ( - - )} - {label} - - ); - })} -
    - ); -} - -export interface BenchRowEntry { - label: ReactNode; - value: string; - highlight?: boolean; -} - -// Splits a stat string into a leading symbol prefix, the numeric portion, and a -// trailing unit suffix so the number can be counted up while the units stay put. -// Returns null when there is no number to animate (e.g. "Infinite"). -function parseStatNumber(text: string) { - const match = text.match(/^([^\d-]*)(-?[\d,]*\.?\d+)(.*)$/); - if (!match) return null; - const [, prefix, rawNumber, suffix] = match; - const normalized = rawNumber.replace(/,/g, ''); - const decimals = normalized.includes('.') ? normalized.split('.')[1].length : 0; - return { - prefix, - suffix, - value: Number.parseFloat(normalized), - decimals, - grouped: rawNumber.includes(','), - }; -} - -// Counts the numeric part of a stat from 0 up to its value. The first run is -// gated on `active` (the card scrolling into view) and only fires once; later -// value changes (toggling workload or tier) re-trigger the count from the -// previous value. Honors reduced-motion by rendering the final value outright. -export function CountUpStat({ text, active }: { text: string; active: boolean }) { - const parsed = useMemo(() => parseStatNumber(text), [text]); - const reducedMotion = useReducedMotion(); - const target = parsed?.value ?? 0; - - const [display, setDisplay] = useState(0); - const startedRef = useRef(false); - const fromRef = useRef(0); - const rafRef = useRef(0); - - useEffect(() => { - if (!parsed) return; - if (reducedMotion) { - setDisplay(target); - fromRef.current = target; - startedRef.current = true; - return; - } - // Not yet scrolled into view: stay primed at zero for the first count-up. - if (!active) { - if (!startedRef.current) setDisplay(0); - return; - } - const from = startedRef.current ? fromRef.current : 0; - startedRef.current = true; - const duration = 850; - let start = 0; - const step = (now: number) => { - if (!start) start = now; - const t = Math.min(1, (now - start) / duration); - const eased = 1 - (1 - t) ** 3; - setDisplay(from + (target - from) * eased); - if (t < 1) { - rafRef.current = requestAnimationFrame(step); - } else { - fromRef.current = target; - } - }; - rafRef.current = requestAnimationFrame(step); - return () => cancelAnimationFrame(rafRef.current); - }, [parsed, target, active, reducedMotion]); - - if (!parsed) return <>{text}; - - const formatted = parsed.grouped - ? display.toLocaleString(undefined, { - minimumFractionDigits: parsed.decimals, - maximumFractionDigits: parsed.decimals, - }) - : display.toFixed(parsed.decimals); - - return ( - - {parsed.prefix} - {formatted} - {parsed.suffix} - - ); -} - -// Light data card with a sans title, headline stat, -// and label/value rows pinned to the card's foot. -export function BenchCard({ - title, - statNote, - verb, - toggle, - rows, - note, -}: { - title: string; - statNote: string; - verb?: string; - toggle?: ReactNode; - rows: BenchRowEntry[]; - note?: string; -}) { - // Trigger the count-up the first time the card scrolls into view, once. - const [inView, setInView] = useState(false); - - return ( -
    - setInView(true)} - viewport={{ once: true, margin: '-10% 0px' }} - > - {/* Eyebrow rail */} -
    - {title} -
    - - {/* Verdict: the headline multiplier */} -
    - - - - {verb ? {verb} : null} -
    - - {/* Comparison ledger: ours vs theirs, same unit, right-aligned */} -
    - {rows.map((row, i) => ( -
    - - {row.label} - - - {row.value} - -
    - ))} -
    - - {toggle} - {note ? ( -

    {note}

    - ) : null} -
    -
    - ); -} diff --git a/src/components/marketing/components/CopyCommand.tsx b/src/components/marketing/components/CopyCommand.tsx deleted file mode 100644 index 72d7bb58..00000000 --- a/src/components/marketing/components/CopyCommand.tsx +++ /dev/null @@ -1,58 +0,0 @@ -'use client'; - -import { Icon, faArrowRight, faCheck, faCopy } from '@rivet-gg/icons'; -import clsx from 'clsx'; -import { useState } from 'react'; - -interface CopyCommandProps { - children?: string; - command?: string; - className?: string; -} - -export function CopyCommand({ children, command, className }: CopyCommandProps) { - const [copied, setCopied] = useState(false); - - const handleCopy = () => { - const commandText = command || children || ''; - const textToCopy = commandText.startsWith('$') ? commandText.substring(1).trim() : commandText; - - navigator.clipboard.writeText(textToCopy); - - setCopied(true); - setTimeout(() => { - setCopied(false); - }, 1000); - }; - - return ( -
    -
    - -
    - -
    - {command || children} -
    - -
    -
    - -
    -
    - -
    -
    -
    - ); -} diff --git a/src/components/marketing/components/Icon.tsx b/src/components/marketing/components/Icon.tsx deleted file mode 100644 index 9b2c7a85..00000000 --- a/src/components/marketing/components/Icon.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { - faArrowRight, - faBluesky, - faBolt, - faCheck, - faChevronLeft, - faChevronRight, - faCloud, - faCopy, - faDatabase, - faDiscord, - faFilePen, - faGamepad, - faGaugeHigh, - faGithub, - faGlobe, - faLock, - faMessage, - faMicrochip, - faReact, - faRobot, - faRotate, - faServer, - faShapes, - faSquareQuestion, - faTowerBroadcast, - faWaveSine, - faXTwitter -} from '@rivet-gg/icons'; - -import { Icon as RivetIcon } from '@rivet-gg/icons'; - -interface IconProps { - icon: string; - color?: string; - size?: number; - className?: string; - iconType?: 'solid' | 'brands'; -} - -const iconMap = { - robot: faRobot, - message: faMessage, - database: faDatabase, - shapes: faShapes, - 'arrow-right': faArrowRight, - 'chevron-left': faChevronLeft, - 'chevron-right': faChevronRight, - 'file-pen': faFilePen, - 'gauge-high': faGaugeHigh, - 'wave-sine': faWaveSine, - gamepad: faGamepad, - rotate: faRotate, - 'square-question': faSquareQuestion, - discord: faDiscord, - github: faGithub, - 'x-twitter': faXTwitter, - bluesky: faBluesky, - copy: faCopy, - check: faCheck, - microchip: faMicrochip, - bolt: faBolt, - 'tower-broadcast': faTowerBroadcast, - globe: faGlobe, - cloud: faCloud, - server: faServer, - lock: faLock, - react: faReact -}; - -export function Icon({ icon, color = 'white', size = 16, className = '', iconType = 'solid' }: IconProps) { - const iconDef = iconMap[icon as keyof typeof iconMap]; - - if (!iconDef) { - console.warn(`Icon "${icon}" not found in iconMap`); - return null; - } - - return ( - - ); -} diff --git a/src/components/marketing/deployKit.tsx b/src/components/marketing/deployKit.tsx index 672e7867..42a01fee 100644 --- a/src/components/marketing/deployKit.tsx +++ b/src/components/marketing/deployKit.tsx @@ -19,7 +19,6 @@ export const DEPLOY_COMMAND_BLOCK_CLASS = export const DEPLOY_CARD_CLASS = 'relative flex h-full flex-col rounded-xl border border-ink/10 bg-white/55 p-6 md:p-8'; export const DEPLOY_CARD_TITLE_CLASS = CARD_TITLE_CLASS; -export const DEPLOY_BUTTON_BASE = 'w-full'; export const DEPLOY_GHOST_BUTTON_CLASS = `${PRODUCT_HERO_SECONDARY_BUTTON_CLASS} !w-full no-underline`; export const DEPLOY_WHITE_BUTTON_CLASS = `${PRIMARY_INK_BUTTON_CLASS} !w-full no-underline`; diff --git a/src/components/marketing/diagrams/AgentStack.tsx b/src/components/marketing/diagrams/AgentStack.tsx deleted file mode 100644 index a50ce147..00000000 --- a/src/components/marketing/diagrams/AgentStack.tsx +++ /dev/null @@ -1,129 +0,0 @@ -'use client'; - -import { motion, useReducedMotion } from 'framer-motion'; -import { EASE, VIEWPORT } from '../motion'; - -// --------------------------------------------------------------------------- -// The architecture as containment: your backend is the outer box. Inside it, -// your code drives sessions into per-agent agentOS VMs. Each VM pairs a -// guest — an off-the-shelf agent like Pi, or one you build with a framework -// like Eve or Flue, on Node, Python, and shell, running on WASM — with its own virtual kernel that services every syscall. The -// library hosts the VMs in a sidecar process it manages, so "your backend" -// is the deployment boundary rather than a literal single process — and -// there is no hypervisor or container in the path. White cards are elements -// of your backend, light chips are guest workloads, ink bars are the -// per-VM kernels. -// --------------------------------------------------------------------------- - -// Eve's mark is its wordmark, so it renders wider and shorter than the -// square marks. -const VMS = [ - { - agent: 'Pi', - marks: [{ src: '/images/agent-logos/pi.svg', className: 'h-4 w-4 object-contain' }], - }, - { - agent: 'your agent', - marks: [ - { src: '/images/frameworks/eve.svg', className: 'h-2.5 w-auto object-contain' }, - { src: '/images/frameworks/flue.svg', className: 'h-4 w-4 object-contain' }, - ], - }, -]; - -// A dashed vertical connector with a label beside it and, unless reduced -// motion is on, a dot travelling the flow path. -const Connector = ({ label, reduced, delay }: { label?: string; reduced: boolean | null; delay: number }) => ( -
    - - {label && {label}} -
    -); - -const Appear = ({ at, reduced, children, className }: { at: number; reduced: boolean | null; children: React.ReactNode; className?: string }) => ( - - {children} - -); - -export const AgentStack = () => { - const reduced = useReducedMotion(); - return ( -
    - {/* Outer box: your backend */} -
    - Your backend -
    - - {/* The driver: your code holds the sessions */} - -
    - your code -
    -
    - - {/* Driver -> VMs: one session per agent */} -
    - - - - drives sessions - -
    - - {/* Per-agent agentOS VMs */} -
    - {VMS.map((vm, i) => ( - -

    - agentOS vm -

    - - {/* Guest: the agent and its execution engines */} -
    -
    - {vm.marks.map((mark) => ( - - ))} - {vm.agent} -
    -

    node · python · shell

    -

    on wasm

    -
    - - - - {/* The per-VM virtual kernel */} -
    - virtual kernel -

    fs · processes · sockets · permissions

    -
    -
    - ))} -
    - - {/* What is not in the path */} -

    no hypervisor · no containers

    -
    - ); -}; diff --git a/src/components/marketing/diagrams/ColdStartRace.tsx b/src/components/marketing/diagrams/ColdStartRace.tsx deleted file mode 100644 index 8c3b0b1d..00000000 --- a/src/components/marketing/diagrams/ColdStartRace.tsx +++ /dev/null @@ -1,240 +0,0 @@ -'use client'; - -import { animate, motion, useInView, useMotionValue, useTransform, useReducedMotion } from 'framer-motion'; -import type { MotionValue } from 'framer-motion'; -import { useEffect, useRef, useState } from 'react'; -import type { ReactNode } from 'react'; -import { Box, Check } from 'lucide-react'; -import { Reveal } from '../motion'; -import { BenchToggle, BenchInfoTooltip } from './benchUI'; -import { benchColdStart, SANDBOX_COLDSTART_PROVIDER, BENCHMARK_DATE } from '../../../data/bench'; - -// --------------------------------------------------------------------------- -// Cold-start comparison. Two hosts spin up agents, once, when scrolled into view. -// Containers — each agent gets its own process: a separate box that boots on -// its own (border red -> green + mini bar). -// agentOS — every agent is packed into ONE shared process: a single box -// that boots once. -// The contrast (four separate boots vs one grouped boot) is the point. The -// container boot is shown slowed ~6x so the wait is visible. Numbers come from -// bench.ts so they stay accurate. -// --------------------------------------------------------------------------- - -const AGENTOS_MARK = '/images/agent-os/agentos-logo-ink.svg'; -const AGENT_LOGOS = [ - '/images/agent-logos/pi.svg', - '/images/agent-logos/claude-code.svg', - '/images/agent-logos/codex.svg', - '/images/agent-logos/opencode.svg', -]; -const agentAt = (i: number) => AGENT_LOGOS[(i * 7) % AGENT_LOGOS.length]; - -const RED = '#d6453a'; -const GREEN = '#3f9a59'; -const BORDER_RED = 'rgba(214,69,58,0.6)'; -const BORDER_GREEN = 'rgba(63,154,89,0.65)'; - -// ---- Animation timing ------------------------------------------------------ -// The boot is scaled to each percentile's REAL container cold start, always -// slowed 6x — so p99 crawls ~6x longer than p50, in true proportion. -const SLOWDOWN = 6; -// agentOS boots near-instantly, so its box snaps done in a fixed, snappy time — -// independent of the container's 6x slowdown. It must never appear to "wait". -const AOS_BOOT_SEC = 0.5; -const bootDuration = (containerMs: number) => (containerMs / 1000) * SLOWDOWN; -const slowdownFactor = (containerMs: number) => (bootDuration(containerMs) * 1000) / containerMs; -const slowdownLabel = (containerMs: number) => { - const factor = slowdownFactor(containerMs); - return factor < 1.4 ? 'in real time' : `slowed ~${Math.round(factor)}×`; -}; -// Pill copy for the containers row. Phrased as a playback note so it reads as a -// display speed, not a perf claim that would clash with agentOS's "Nx faster". -const slowdownPill = (containerMs: number) => { - const factor = slowdownFactor(containerMs); - return factor < 1.4 ? 'shown in real time' : `shown ~${Math.round(factor)}× slower`; -}; - -const MiniBar = ({ width, color }: { width: MotionValue; color: MotionValue }) => ( -
    - -
    -); - -// One container: its own agent, booting on its own. -const ContainerBox = ({ progress, lo, hi, logo }: { progress: MotionValue; lo: number; hi: number; logo: string }) => { - const border = useTransform(progress, [lo, hi], [BORDER_RED, BORDER_GREEN]); - const barWidth = useTransform(progress, [lo, hi], ['14%', '100%']); - const barColor = useTransform(progress, [lo, hi], [RED, GREEN]); - return ( -
    - - - - -
    - ); -}; - -// agentOS: all agents packed inside ONE process box that boots once. -const SharedProcessBox = ({ progress, count, doneAt }: { progress: MotionValue; count: number; doneAt: number }) => { - const border = useTransform(progress, [0, doneAt], [BORDER_RED, BORDER_GREEN]); - const barWidth = useTransform(progress, [0, doneAt], ['14%', '100%']); - const barColor = useTransform(progress, [0, doneAt], [RED, GREEN]); - return ( -
    - -
    - {Array.from({ length: count }).map((_, i) => ( - - - - ))} -
    -
    - -
    - ); -}; - -type HostCfg = { - name: ReactNode; - finalMs: number; - doneAt: number; - units: number; - grouped: boolean; // agentOS packs all agents into one process box - accent: boolean; - badge?: ReactNode; -}; - -const Host = ({ cfg, progress }: { cfg: HostCfg; progress: MotionValue }) => { - const counter = useTransform(progress, (p) => `~${Math.round(Math.min(1, p / cfg.doneAt) * cfg.finalMs)} ms`); - const checkOpacity = useTransform(progress, [0, cfg.doneAt * 0.95, cfg.doneAt], [0, 0, 1]); - return ( -
    -
    - {cfg.name} -
    - {cfg.badge} - - {counter} -
    -
    - {cfg.grouped ? ( - - ) : ( -
    - {Array.from({ length: cfg.units }).map((_, i) => { - const lo = (i / cfg.units) * 0.08; - return ; - })} -
    - )} -
    - ); -}; - -export const ColdStartRace = () => { - const reduced = useReducedMotion(); - const ref = useRef(null); - const inView = useInView(ref, { once: true, margin: '-15% 0px' }); - const progress = useMotionValue(0); // containers — slowed boot - const aosProgress = useMotionValue(0); // agentOS — fixed snappy boot - const [pct, setPct] = useState(0); // p50 by default - - const cold = benchColdStart[pct]; - const aosMs = Math.round(cold.agentOS); - const containerMs = cold.sandbox; - const speedup = Math.round(cold.sandbox / cold.agentOS); - const durationSec = bootDuration(containerMs); - - // Play the boot once it scrolls into view; replay when the percentile changes. - // The containers crawl over the slowed duration; agentOS snaps done in a fixed - // fast time so it never appears to scale with the container slowdown. - useEffect(() => { - if (reduced) { - progress.set(1); - aosProgress.set(1); - return; - } - if (!inView) return; - progress.set(0); - aosProgress.set(0); - const c1 = animate(progress, [0, 1], { duration: durationSec, ease: 'easeInOut' }); - const c2 = animate(aosProgress, [0, 1], { duration: AOS_BOOT_SEC, ease: 'easeOut' }); - return () => { - c1.stop(); - c2.stop(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [inView, reduced, pct]); - - return ( - -
    -
    -
    - Cold start - {slowdownPill(containerMs)} -
    -
    - g.label)} active={pct} onChange={setPct} /> -
    -
    - -
    - -
    - -

    - Each container is its own process that boots on its own; agentOS packs every agent into one shared process that boots once. Real {cold.label} cold start: ~{aosMs} ms vs ~{containerMs.toLocaleString()} ms ({speedup}× faster) — container boot shown {slowdownLabel(containerMs)}. -

    -
    -
    - ); -}; diff --git a/src/components/marketing/diagrams/ColdStartTimeline.tsx b/src/components/marketing/diagrams/ColdStartTimeline.tsx deleted file mode 100644 index 70f331ac..00000000 --- a/src/components/marketing/diagrams/ColdStartTimeline.tsx +++ /dev/null @@ -1,253 +0,0 @@ -'use client'; - -import { animate, motion, useMotionValue, useMotionValueEvent, useReducedMotion } from 'framer-motion'; -import { X } from 'lucide-react'; -import { useEffect, useRef, useState } from 'react'; -import { COLDSTART_P99_MS, SANDBOX_COLDSTART_MS } from '../../../data/bench'; - -// --------------------------------------------------------------------------- -// Cold-start anatomy, shown in the modal behind the comparison table's Startup -// row. Two stacked cards: a sandbox cold start as a sequential waterfall (API -// call, scheduling, boot, re-auth), and agentOS as a single tick so thin it -// needs a magnified inset to be visible at all. A shared clock counts the -// timeline in ms while the bars fill. Totals come from bench.ts; the sandbox -// step split is illustrative anatomy that sums to the measured p99 total. -// --------------------------------------------------------------------------- - -const AXIS_MAX_MS = 3500; -const INSET_MAX_MS = 8; -// Wall-clock seconds per timeline millisecond: the full 3.5 s timeline plays -// in ~2.6 s. -const K = 0.00075; - -const SANDBOX_TOTAL = SANDBOX_COLDSTART_MS.p99; -const STEP_OVERHEAD = 200; -const SANDBOX_STEPS = [ - { label: 'API call to provider', start: 0, dur: STEP_OVERHEAD }, - { label: 'Orchestration / scheduling', start: STEP_OVERHEAD, dur: STEP_OVERHEAD }, - { label: 'Boot microVM & pull image', start: STEP_OVERHEAD * 2, dur: SANDBOX_TOTAL - STEP_OVERHEAD * 3 }, - { label: 'Re-authenticate agent against API', start: SANDBOX_TOTAL - STEP_OVERHEAD, dur: STEP_OVERHEAD }, -]; -const MAGNIFICATION = Math.round(AXIS_MAX_MS / INSET_MAX_MS); -const TICKS = [0, 500, 1000, 1500, 2000, 2500, 3000, 3500]; -// The magnified fill is a near-instant sweep: on the shared clock the whole -// agentOS boot is ~6 timeline-ms, so it must read as already finished while -// the sandbox is still on its first step, matching the tick on the main axis. -const INSET_FILL_SEC = 0.22; - -const pct = (ms: number) => `${(ms / AXIS_MAX_MS) * 100}%`; - -const fmt = (ms: number) => `${ms.toLocaleString('en-US')} ms`; - -// Vertical gridlines shared by both timeline bodies. -const Gridlines = () => ( - -); - -const CARD_CLASS = - 'rounded-2xl bg-white/55 ring-1 ring-ink/[0.08] shadow-[inset_0_1px_0_rgba(255,255,255,0.9)]'; - -export const ColdStartTimeline = ({ onClose }: { onClose?: () => void }) => { - const reduced = useReducedMotion(); - const [run, setRun] = useState(false); - const clock = useMotionValue(0); - // The clock writes straight to the DOM node: a per-frame setState here - // would re-render the whole timeline ~60 times a second and drop frames. - const clockRef = useRef(null); - - useMotionValueEvent(clock, 'change', (v) => { - if (clockRef.current) clockRef.current.textContent = Math.round(v).toLocaleString('en-US'); - }); - - // The component mounts when the modal opens, so the sequence starts on - // mount rather than on scroll. - useEffect(() => { - setRun(true); - if (reduced) { - clock.set(AXIS_MAX_MS); - return; - } - const controls = animate(clock, AXIS_MAX_MS, { duration: AXIS_MAX_MS * K, ease: 'linear', delay: 0.2 }); - return () => controls.stop(); - }, [reduced, clock]); - - // Fills animate scaleX (compositor-only) instead of width, with the final - // width set statically; with reduced motion bars render settled. - const bar = (startMs: number, durMs: number) => - reduced - ? { initial: { scaleX: 1 }, animate: { scaleX: 1 } } - : { - initial: { scaleX: 0 }, - animate: run ? { scaleX: 1 } : { scaleX: 0 }, - transition: { duration: durMs * K, delay: 0.2 + startMs * K, ease: 'linear' as const }, - }; - - const appear = (atMs: number, extraDelay = 0) => - reduced - ? { initial: { opacity: 1 }, animate: { opacity: 1 } } - : { - initial: { opacity: 0 }, - animate: run ? { opacity: 1 } : { opacity: 0 }, - transition: { duration: 0.25, delay: 0.2 + atMs * K + extraDelay }, - }; - - return ( -
    - {/* Header: title left; the running clock and close control share the - right side with real spacing instead of stacking in the corner. */} -
    - Cold-start timeline -
    - - t = 0 ms - - {onClose && ( - - )} -
    -
    - - {/* Sandbox waterfall */} -
    -
    -

    - microVM sandboxes · separate infrastructure (p99, fastest - provider) -

    - - Total: {fmt(SANDBOX_TOTAL)} - -
    - -
    - {SANDBOX_STEPS.map((step, i) => ( -
    -
    - {i + 1} - {step.label} -
    -
    - - {/* Dashed marker at the measured total */} -
    -
    - ))} -
    -
    - - {/* agentOS: a tick at zero, with a magnified inset */} -
    -
    -

    - agentOS · WebAssembly, in-process (p99) -

    - - Total: {COLDSTART_P99_MS} ms - -
    - -
    -
    - Boot agentOS VM -
    -
    - - -
    -
    - - {/* Time axis */} -
    -
    - {TICKS.map((t) => ( - - {t.toLocaleString('en-US')} - - ))} -
    - - {/* Dashed connectors from the origin down to the inset */} - - - {/* Magnified inset */} - -
    - - {MAGNIFICATION}× magnified - -
    -
    - - {/* At this magnification 6.1 ms takes as long as the whole sandbox - timeline above, so the fill runs the full clock duration. */} - - - {COLDSTART_P99_MS} ms - -
    -
    - {[0, 2, 4, 6, 8].map((t) => ( - - {t} - - ))} -
    -
    -
    -
    -
    - ); -}; diff --git a/src/components/marketing/diagrams/ExecutionDensity.tsx b/src/components/marketing/diagrams/ExecutionDensity.tsx deleted file mode 100644 index 86b38ed9..00000000 --- a/src/components/marketing/diagrams/ExecutionDensity.tsx +++ /dev/null @@ -1,221 +0,0 @@ -'use client'; - -import { motion, useReducedMotion } from 'framer-motion'; -import { useEffect, useRef, useState } from 'react'; -import type { ReactNode } from 'react'; -import { Server, Container, SquareTerminal } from 'lucide-react'; -import { EASE, VIEWPORT, Reveal } from '../motion'; -import { BenchToggle, CountUpStat, BenchInfoTooltip } from './benchUI'; -import { benchWorkloads, SANDBOX_COST_PROVIDER, BENCHMARK_DATE, type WorkloadKey } from '../../../data/bench'; - -// --------------------------------------------------------------------------- -// Cost-per-execution-second, told as a density story. One server packs N -// concurrent executions (N = executions that fit per server at 70% utilization, -// from bench.ts) while a sandbox holds exactly one. The packed count is the -// denominator of the cost, so the packing animation resolves into the price: -// one $X/hr server / N executions = $Y per execution-second. -// Laid out as a full-width horizontal card. Driven by the shared workload toggle -// plus a local hardware-tier toggle. -// --------------------------------------------------------------------------- - -const WORKLOAD_KEYS = Object.keys(benchWorkloads) as WorkloadKey[]; -const AGENT_LOGOS = [ - '/images/agent-logos/pi.svg', - '/images/agent-logos/claude-code.svg', - '/images/agent-logos/codex.svg', - '/images/agent-logos/opencode.svg', -]; -const CHIP_CAP = 48; // cap rendered chips; the rest fold into a "+N more" pill - -// Smoothly animates its own height to match its content. A ResizeObserver tracks -// the inner element's natural height (unaffected by child transforms), so when -// the packed-chip count changes the card grows/shrinks instead of jumping. The -// inner element keeps its real size — nothing is scaled — so no text distortion. -function AutoHeight({ children }: { children: ReactNode }) { - const reduced = useReducedMotion(); - const innerRef = useRef(null); - const [height, setHeight] = useState('auto'); - - useEffect(() => { - const el = innerRef.current; - if (!el) return; - const update = () => setHeight(el.offsetHeight); - update(); - const ro = new ResizeObserver(update); - ro.observe(el); - return () => ro.disconnect(); - }, []); - - return ( - -
    {children}
    -
    - ); -} - -export const ExecutionDensity = ({ workload, onWorkloadChange }: { workload: WorkloadKey; onWorkloadChange: (w: WorkloadKey) => void }) => { - const reduced = useReducedMotion(); - const [tierIdx, setTierIdx] = useState(0); // Hetzner ARM default - const [inView, setInView] = useState(false); - - const wl = benchWorkloads[workload]; - const tier = wl.cost[tierIdx]; - const execs = tier.execs; - const [mult, verb] = tier.multiplier.split(' '); // ['171x', 'cheaper'] - const shown = Math.min(execs, CHIP_CAP); - const overflow = execs - shown; - const activeIdx = WORKLOAD_KEYS.indexOf(workload); - - if (overflow > 0 && import.meta.env.DEV) { - console.info(`[ExecutionDensity] ${execs} execs (${workload}/${tier.label}); rendering ${shown} chips +${overflow} more (cap=${CHIP_CAP}).`); - } - - const chipGlyph = (i: number) => - workload === 'agent' ? ( - - ) : ( -