mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
Pages from /machines to /risk, the model pages, and the kits they are made of
(page-kit, ProductLanding, LayerPage, Stack, the models kit, band's Head) mark
authored copy where it is written and draw it in the reader's language. A server
page marks a literal phrase('…') or wraps it in <T>; a client page calls t. The
kits translate a string prop through useSay (components/marketing/say), so a
page passes phrase('…') and markup passes as written. An arrow that points
turns over right to left (data-i18n-mirror).
Rebased on main: the fold-based heroes (Fold, PageHero, MachinesHero, the
product and layer pages) keep main's structure and copy, with their label,
title and lede marked phrase. /platform is main's CloudLanding; the deleted
/platform/layers and the old referral components stay deleted.
Claude-Session: https://claude.ai/code/session_015XYKLjZtDTJEnMo4eK3AFH
86 lines
2.7 KiB
TypeScript
86 lines
2.7 KiB
TypeScript
|
|
/**
|
|
* NO TAILWIND. `Band` + `Head` carry the frame and the centred heading; the
|
|
* three tiles are gui props, centred on their own axis.
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { Shield, Database, Server } from "lucide-react";
|
|
import { View, YStack } from '@/components/ui'
|
|
import { Grid } from '@hanzo/ui/grid'
|
|
import { Band, Head, Words } from '@/components/marketing/band'
|
|
import { phrase } from '@hanzo/i18n'
|
|
import { T } from '@hanzo/i18n/react'
|
|
|
|
/** How narrow a column may get before the grid drops one. */
|
|
const DECK = { min: 304, max: 3 } as const
|
|
|
|
interface EnterpriseFeatureProps {
|
|
icon: React.ComponentType<{ width?: number; height?: number }>;
|
|
title: string;
|
|
description: string;
|
|
}
|
|
|
|
const EnterpriseFeature = ({ icon: Icon, title, description }: EnterpriseFeatureProps) => {
|
|
return (
|
|
<YStack
|
|
items="center"
|
|
p={24}
|
|
rounded="var(--radius-xl)"
|
|
background="color-mix(in srgb, var(--primary) 5%, transparent)"
|
|
border="1px solid color-mix(in srgb, var(--primary) 20%, transparent)"
|
|
$platform-web={{ textAlign: 'center' }}
|
|
>
|
|
<View mb={16}>
|
|
<Icon width={48} height={48} />
|
|
</View>
|
|
<Words render="h3" mb={8} fontSize="$6" lineHeight="1.4" weight="700" color="var(--foreground)"><T>{title}</T></Words>
|
|
<Words render="p" color="var(--muted-foreground)">
|
|
<T>{description}</T>
|
|
</Words>
|
|
</YStack>
|
|
);
|
|
};
|
|
|
|
const MachinesEnterprise = () => {
|
|
const features = [
|
|
{
|
|
icon: Shield,
|
|
title: phrase("Scoped to your organization"),
|
|
description: phrase("A machine belongs to one org and is named within it. Every read and every terminate is checked against the org on your token, not against the id in the URL.")
|
|
},
|
|
{
|
|
icon: Database,
|
|
title: phrase("Bring your own account"),
|
|
description: phrase("Link a DigitalOcean, AWS or GCP account and the clusters it holds fold into the same fleet. Your capacity, your contract, one place to see it.")
|
|
},
|
|
{
|
|
icon: Server,
|
|
title: phrase("Pick the region deliberately"),
|
|
description: phrase("Launches name a region from the list the API returns, so where a workload runs is a decision you made rather than one that was made for you.")
|
|
}
|
|
];
|
|
|
|
return (
|
|
<Band rule={false}>
|
|
<Head
|
|
title={phrase("Whose machine it is")}
|
|
lede={phrase("Ownership, region and account are decisions the API makes you state")}
|
|
/>
|
|
|
|
<Grid columns={DECK} gap={32}>
|
|
{features.map((feature, index) => (
|
|
<EnterpriseFeature
|
|
key={index}
|
|
icon={feature.icon}
|
|
title={feature.title}
|
|
description={feature.description}
|
|
/>
|
|
))}
|
|
</Grid>
|
|
</Band>
|
|
);
|
|
};
|
|
|
|
export default MachinesEnterprise;
|