mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
109 lines
3.4 KiB
TypeScript
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;
|