diff --git a/src/components/shared/header/menu-feature-cards/index.js b/src/components/shared/header/menu-feature-cards/index.js
new file mode 100644
index 00000000000..2b641f20df0
--- /dev/null
+++ b/src/components/shared/header/menu-feature-cards/index.js
@@ -0,0 +1,3 @@
+import MenuFeatureCards from './menu-feature-cards';
+
+export default MenuFeatureCards;
diff --git a/src/components/shared/header/menu-feature-cards/menu-feature-cards.jsx b/src/components/shared/header/menu-feature-cards/menu-feature-cards.jsx
new file mode 100644
index 00000000000..b8910e18b48
--- /dev/null
+++ b/src/components/shared/header/menu-feature-cards/menu-feature-cards.jsx
@@ -0,0 +1,160 @@
+import PropTypes from 'prop-types';
+
+import Link from 'components/shared/link';
+import ArrowTopRightIcon from 'icons/arrow-right.inline.svg';
+import { cn } from 'utils/cn';
+
+const DatabaseIcon = ({ className }) => (
+
+);
+
+DatabaseIcon.propTypes = {
+ className: PropTypes.string,
+};
+
+const NeonMark = ({ className }) => (
+
+);
+
+NeonMark.propTypes = {
+ className: PropTypes.string,
+};
+
+const AgentsGraphic = () => (
+
+
+
+
+
+
+
+
+
+);
+
+const PLATFORM_TILES = [false, true, false, true, false, false, false, false, true];
+
+const PlatformsGraphic = () => (
+
+ {PLATFORM_TILES.map((isHighlighted, index) => (
+
+ ))}
+
+);
+
+const GRAPHICS = {
+ agents: AgentsGraphic,
+ platforms: PlatformsGraphic,
+};
+
+const MenuFeatureCards = ({
+ items,
+ linkProps: { className, ...linkProps } = {},
+ className: wrapperClassName,
+}) => (
+
+ {items.map(({ title, description, to, isExternal, graphic }) => {
+ const Graphic = GRAPHICS[graphic];
+
+ return (
+ -
+
+ {Graphic &&
}
+
+
+ {title}
+
+
+
+ {description}
+
+
+
+
+ );
+ })}
+
+);
+
+MenuFeatureCards.propTypes = {
+ items: PropTypes.arrayOf(
+ PropTypes.shape({
+ title: PropTypes.string.isRequired,
+ description: PropTypes.string,
+ to: PropTypes.string.isRequired,
+ isExternal: PropTypes.bool,
+ graphic: PropTypes.oneOf(['agents', 'platforms']),
+ })
+ ).isRequired,
+ linkProps: Link.propTypes,
+ className: PropTypes.string,
+};
+
+export default MenuFeatureCards;
diff --git a/src/components/shared/header/mobile-menu/mobile-menu.jsx b/src/components/shared/header/mobile-menu/mobile-menu.jsx
index 8ad99bff08d..5af29d5b4c4 100644
--- a/src/components/shared/header/mobile-menu/mobile-menu.jsx
+++ b/src/components/shared/header/mobile-menu/mobile-menu.jsx
@@ -16,6 +16,7 @@ import { cn } from 'utils/cn';
import Burger from '../burger';
import MenuBanner from '../menu-banner';
+import MenuFeatureCards from '../menu-feature-cards';
const ANIMATION_DURATION = 0.2;
@@ -60,31 +61,35 @@ const MobileMenuItem = ({ text, to, sections, ...otherProps }) => {
className="flex gap-x-3.5 md:flex-col md:gap-y-9"
>
- {sections.map(({ title, items }, index) => (
- -
+ {sections.map(({ title, items, variant }, index) => (
+
-
{title && (
{title}
)}
-
- {items.map(({ title, description, to, isExternal }) => (
- -
-
-
- {title}
-
+ {variant === 'cards' ? (
+
+ ) : (
+
+ {items.map(({ title, description, to, isExternal }) => (
+ -
+
+
+ {title}
+
- {description}
-
-
- ))}
-
+ {description}
+
+
+ ))}
+
+ )}
))}
diff --git a/src/components/shared/header/submenu/submenu.jsx b/src/components/shared/header/submenu/submenu.jsx
index e43004cb54f..2f4f7ccc0fe 100644
--- a/src/components/shared/header/submenu/submenu.jsx
+++ b/src/components/shared/header/submenu/submenu.jsx
@@ -6,6 +6,7 @@ import MENUS from 'constants/menus.js';
import { cn } from 'utils/cn';
import MenuBanner from '../menu-banner';
+import MenuFeatureCards from '../menu-feature-cards';
const Submenu = ({
activeMenuIndex,
@@ -56,8 +57,12 @@ const Submenu = ({
size="1920"
>
- {sections.map(({ title, items }, sectionIndex) => (
- -
+ {sections.map(({ title, items, variant }, sectionIndex) => (
+
-
{title && (
)}
-
- {items?.map(({ title, description, to, isExternal }) => (
- -
-
-
- {title}
-
- {description}
-
-
- ))}
-
+ {variant === 'cards' ? (
+
+ ) : (
+
+ {items?.map(({ title, description, to, isExternal }) => (
+ -
+
+
+ {title}
+
+ {description}
+
+
+ ))}
+
+ )}
))}
diff --git a/src/constants/menus.js b/src/constants/menus.js
index 4d2696192ed..cf477d8b10c 100644
--- a/src/constants/menus.js
+++ b/src/constants/menus.js
@@ -74,39 +74,42 @@ export default {
title: 'Use cases',
items: [
{
- title: 'Serverless App',
- to: `${LINKS.useCases}/serverless-apps`,
- description: 'Autoscale with traffic',
+ title: 'Full-stack apps',
+ to: `${LINKS.useCases}/full-stack-apps`,
+ description: 'Deploy backends via your agent',
},
{
- title: 'Multi-TB',
- to: `${LINKS.useCases}/multi-tb`,
- description: 'Scale and restore instantly',
+ title: 'Branching workflows',
+ to: `${LINKS.useCases}/branching-workflows`,
+ description: 'Simplify DB ops to ship faster & safer',
},
{
- title: 'Database per tenant',
- to: `${LINKS.useCases}/database-per-tenant`,
- description: 'Data isolation without overhead',
+ title: 'Bursty workloads',
+ to: `${LINKS.useCases}/bursty-workloads`,
+ description: 'Avoid overprovisioning & optimize performance',
+ },
+ {
+ title: 'Large databases',
+ to: `${LINKS.useCases}/large-databases`,
+ description: 'Restore & replicate your DB in seconds',
},
],
},
{
- title: 'Build & operate',
+ title: 'Deploy at scale',
+ variant: 'cards',
items: [
- {
- title: 'Platforms',
- to: LINKS.platforms,
- description: 'Offer Postgres for your users',
- },
- {
- title: 'Dev/Tests',
- to: `${LINKS.useCases}/dev-test`,
- description: 'Production-like environment',
- },
{
title: 'Agents',
to: `${LINKS.useCases}/ai-agents`,
- description: 'Build full-stack AI agents',
+ description: 'Infra for app generation agents - used by Replit, v0, and others',
+ graphic: 'agents',
+ },
+ {
+ title: 'Platforms',
+ to: LINKS.platforms,
+ description: 'Deploy isolated backends for your end users',
+ graphic: 'platforms',
},
],
},