Files
hanzo.ai/components/family/Hero.tsx
zeekay 6c65e3e941 @hanzo/app 0.2.0: the app SDK, renamed from @hanzo/rooms
Every import, the catalog pin and the docs name @hanzo/app and
github.com/hanzoai/app. lib/rooms.ts is lib/app.ts and
components/rooms.tsx is components/app.tsx.
2026-10-22 19:07:20 -07:00

108 lines
3.3 KiB
TypeScript

'use client'
import type { ReactNode } from 'react'
import { ArrowRight } from 'lucide-react'
import { Box, View, XStack, YStack } from '@hanzo/ui'
import { Action, Chip, Display, Lede, More } from '@hanzo/ui/marketing'
import { Split } from '@/components/home/band'
import { LOGIN } from '@hanzo/app/lib/destination'
/**
* The opening of a model family's page — /enso, /kai and /zen: a chip naming
* the family, the promise, one line of what it is, Try Hanzo (sign-in first,
* as the closing call's) and one more door. With a `figure` the copy stands
* beside it from 1024px; without one it is centred.
*/
export function Hero({
chip,
title,
lede,
action,
figure,
primary,
more,
below,
}: {
chip: string
title: ReactNode
lede: ReactNode
/** The second door: docs, benchmarks or a download. */
action: { label: string; href: string }
figure?: ReactNode
/** The loud door. Absent, it stays Try Hanzo into sign-in, as /kai and /zen. */
primary?: { label: string; href: string }
/** A text link under the two doors. */
more?: { label: string; href: string }
/** A row under the doors, inside the hero's light: a model card's links. */
below?: ReactNode
}) {
const beside = figure != null
const copy = (
<YStack
gap="$5"
items="center"
$platform-web={{ textAlign: 'center' }}
$lg={beside ? { items: 'flex-start', '$platform-web': { textAlign: 'left' } } : undefined}
>
<Chip px={14} py={5} fontSize="$1" lineHeight="$1">
{chip}
</Chip>
{/* The fold's rungs, as on /: 40 to a phone, 52 from 1024. */}
<Display fontSize="$11" $lg={{ fontSize: 'var(--text-6xl)' }} $platform-web={{ textWrap: 'balance' }}>
{title}
</Display>
<Lede maxW={560}>{lede}</Lede>
<XStack mt="$2" flexWrap="wrap" gap="$3" justify="center" $lg={beside ? { justify: 'flex-start' } : undefined}>
<Action href={primary?.href ?? LOGIN} fill>
{primary?.label ?? 'Try Hanzo'} <ArrowRight size={16} />
</Action>
<Action href={action.href}>{action.label}</Action>
</XStack>
{more ? <More href={more.href}>{more.label}</More> : null}
{below}
</YStack>
)
return (
<Box
render="section"
position="relative"
overflow="hidden"
px="$4"
pt="$10"
pb="$12"
$sm={{ px: '$5' }}
$md={{ pt: '$12' }}
$lg={{ px: '$6' }}
>
<View
aria-hidden
position="absolute"
t={0}
l="50%"
x="-50%"
width={900}
height={500}
pointerEvents="none"
backgroundImage="radial-gradient(circle, color-mix(in srgb, var(--primary) 12%, transparent) 0%, transparent 68%)"
filter="blur(100px)"
/>
<Box position="relative" z="var(--z-raised)" width="100%" maxW={beside ? 1240 : 896} mx="auto">
{beside ? <Split says={copy}>{figure}</Split> : copy}
</Box>
</Box>
)
}
/** The one line a family page keeps about the other two: where they are compared. */
export function Siblings({ name }: { name: string }) {
return (
<Box render="section" px="$4" pt="$8" $sm={{ px: '$5' }} $lg={{ px: '$6' }} borderTopWidth={1} borderColor="var(--border)">
<XStack justify="center">
<More href="/models">
{name} is one of three Hanzo model families. Compare them →
</More>
</XStack>
</Box>
)
}