Files
hanzo.ai/components/machines/MachinesUseCases.tsx

109 lines
3.4 KiB
TypeScript

/**
* NO TAILWIND. `Band` carries the frame and its own ground — the gradient this
* section fades to is what `Band`'s `ground` prop is for — and `Head` carries
* the centred heading and lede. The four tiles are gui props.
*/
import React from 'react';
import { XStack, YStack } from '@/components/ui'
import { Grid } from '@hanzo/ui/grid'
import { Band, Head, Words } from '@/components/marketing/band'
/** How narrow a column may get before the grid drops one. */
const PAIR = { min: 400, max: 2 } as const
interface UseCaseCardProps {
title: string;
description: string;
features: string[];
}
const UseCaseCard = ({ title, description, features }: UseCaseCardProps) => {
return (
<YStack
p={32}
rounded="var(--radius-xl)"
background="color-mix(in srgb, var(--primary) 5%, transparent)"
border="1px solid color-mix(in srgb, var(--primary) 20%, transparent)"
>
<Words render="h3" mb={16} fontSize="$7" lineHeight="1.3333" weight="700" color="var(--foreground)">{title}</Words>
<Words render="p" mb={16} color="var(--muted-foreground)">
{description}
</Words>
<YStack render="ul" gap={8} $platform-web={{ color: 'var(--muted-foreground)' }}>
{features.map((feature, index) => (
<XStack render="li" key={index} items="flex-start">
<Words mr={8}>•</Words>
<span>{feature}</span>
</XStack>
))}
</YStack>
</YStack>
);
};
const MachinesUseCases = () => {
const useCases = [
{
title: "Training runs",
description: "A job that needs cards for hours and nothing for the rest of the week.",
features: [
"GPU sizes named from the list the API returns",
"GPU-hours metered while the job runs",
"Cancel and the hours used so far are billed, then the job stops"
]
},
{
title: "Serving a model",
description: "A machine that stays up because something is calling it.",
features: [
"Run Hanzo Engine on a card you rented",
"Terminate it when the traffic goes away",
"The bill follows the machine, not a reservation"
]
},
{
title: "Work that will not fit in a request",
description: "Renders, batches and simulations that take longer than an HTTP call.",
features: [
"A queue per GPU, plus a shared any-GPU lane",
"Each item says which node claimed it",
"Read the queue instead of guessing where a job went"
]
},
{
title: "Agents that need a computer",
description: "An agent with a machine under it, launched and torn down as one thing.",
features: [
"Bind a cloud agent to a machine",
"Message it, or stop it, by name",
"Tearing down the pair unbinds the agent first"
]
}
];
return (
<Band rule={false} ground={`linear-gradient(to bottom, transparent, var(--primary)10)`}>
<Head
title="When you want a whole machine"
lede="Reach for one when the work outlasts a request, or needs a card of its own"
/>
<Grid columns={PAIR} gap={32}>
{useCases.map((useCase, index) => (
<UseCaseCard
key={index}
title={useCase.title}
description={useCase.description}
features={useCase.features}
/>
))}
</Grid>
</Band>
);
};
export default MachinesUseCases;