mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
Calculator, captable, careers, cloud, compare, contact and contact-sales, customers, dashboards, dataroom, datastore, dev, download, enso, enterprise, extension, family, integrations, investors, kai, learn, legal and their components say their words through t() in client code, <T> in server components and phrase() where copy is held as data; one sentence is one key, figures and links its arguments. Rebased on main: in every conflict main's file stands (its copy, layout and styling) and only the wrapping is added back, including copy main added since. Claude-Session: https://claude.ai/code/session_015XYKLjZtDTJEnMo4eK3AFH
142 lines
4.6 KiB
TypeScript
142 lines
4.6 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
import { phrase } from '@hanzo/i18n'
|
|
import { T } from '@hanzo/i18n/react'
|
|
import { Box, Text, View, YStack } from '@/components/ui'
|
|
import { Eyebrow, Title, Leaf } from '@hanzo/ui/marketing'
|
|
import { Grid } from '@hanzo/ui/grid'
|
|
import { KAI } from '@/lib/bench-data'
|
|
import { named } from '@/lib/kai'
|
|
import { kaiTiles, record } from '@/lib/tally'
|
|
import { Fact } from '@/components/enso/Lead'
|
|
import { LINEUP, NEXT } from '@/lib/zen'
|
|
|
|
/**
|
|
* The three model families, on /models: what each one does, one fact from its
|
|
* data, and its own page. Each family page is about that family alone; this is
|
|
* the one place the three are set side by side.
|
|
*
|
|
* Every figure is read: Enso's from its research runs when the page opens
|
|
* (components/enso/Lead `Fact`), Zen's generations from lib/zen, Kai's from the
|
|
* research runs (KAI), and Kai's line shows only while a claim holds. A server
|
|
* component, all gui props.
|
|
*/
|
|
|
|
/** Kai's lead line: the suites it leads, every row a research run (lib/tally). */
|
|
const CLAIM = KAI ? kaiTiles(record(KAI.index.wins), named(KAI.run))[0] : undefined
|
|
|
|
const FAMILIES: readonly { name: string; verb: string; body: string; fact?: ReactNode; href: string }[] = [
|
|
{
|
|
name: 'Enso',
|
|
verb: phrase('routes'),
|
|
body: phrase('Picks the model for every call, in every modality.'),
|
|
fact: <Fact />,
|
|
href: '/enso',
|
|
},
|
|
{
|
|
name: 'Kai',
|
|
verb: phrase('decides'),
|
|
body: phrase('Answers a choice, a score or a yes/no, with the probability of each.'),
|
|
fact: CLAIM ? (
|
|
<>
|
|
{CLAIM.figure} · <T>{CLAIM.label}</T>
|
|
</>
|
|
) : undefined,
|
|
href: '/kai',
|
|
},
|
|
{
|
|
name: 'Zen',
|
|
verb: phrase('reasons'),
|
|
body: phrase('Open weights for the code, the copy, the images and the voice.'),
|
|
fact: <T values={{ lineup: LINEUP, next: NEXT.name }}>{'{lineup} now · {next} in research preview'}</T>,
|
|
href: '/zen',
|
|
},
|
|
]
|
|
|
|
/** The card's small lines share a face. */
|
|
const SMALL = { fontFamily: '$mono', fontSize: '$1', lineHeight: '$1' } as const
|
|
|
|
export function Family() {
|
|
return (
|
|
<Box
|
|
render="section"
|
|
aria-labelledby="family-title"
|
|
position="relative"
|
|
py="$11"
|
|
px="$4"
|
|
$sm={{ px: '$5' }}
|
|
$lg={{ px: '$6' }}
|
|
borderTopWidth={1}
|
|
borderColor="var(--border)"
|
|
>
|
|
<Grid columns={1} gap={40} width="100%" maxW={1024} mx="auto">
|
|
<Grid columns={1} gap={14} width="100%" maxW={672} mx="auto" $platform-web={{ textAlign: 'center' }}>
|
|
<Eyebrow>
|
|
<T>Three families</T>
|
|
</Eyebrow>
|
|
<Title id="family-title">
|
|
<T>Enso routes. Kai decides. Zen reasons.</T>
|
|
</Title>
|
|
</Grid>
|
|
|
|
<View
|
|
render="ol"
|
|
display="grid"
|
|
gridTemplateColumns="minmax(0, 1fr)"
|
|
$md={{ gridTemplateColumns: 'repeat(3, minmax(0, 1fr))' }}
|
|
gap="$4"
|
|
m={0}
|
|
p={0}
|
|
>
|
|
{FAMILIES.map((f) => (
|
|
<YStack render="li" key={f.name}>
|
|
<Leaf
|
|
href={f.href}
|
|
width="100%"
|
|
height="100%"
|
|
display="flex"
|
|
flexDirection="column"
|
|
gap="$2"
|
|
p="$5"
|
|
borderColor="$edge"
|
|
bg="$panel"
|
|
transition="quickest"
|
|
hoverStyle={{ borderColor: 'var(--border-strong)' }}
|
|
focusVisibleStyle={{ borderColor: 'var(--border-strong)' }}
|
|
>
|
|
<Text {...SMALL} color="var(--text-tertiary)">
|
|
<T>{f.verb}</T>
|
|
</Text>
|
|
<Text fontSize="$7" lineHeight="$8" fontWeight="600" color="$ink">
|
|
{f.name}
|
|
</Text>
|
|
<Text mt="$1" fontSize="$3" lineHeight="$3" color="var(--text-secondary)">
|
|
<T>{f.body}</T>
|
|
</Text>
|
|
{f.fact ? (
|
|
<Text {...SMALL} mt="$2" color="var(--muted-foreground)">
|
|
{f.fact}
|
|
</Text>
|
|
) : null}
|
|
<Text
|
|
mt="auto"
|
|
pt="$4"
|
|
fontSize="$2"
|
|
fontWeight="500"
|
|
color="$soft"
|
|
transition="quickest"
|
|
$group-hover={{ color: '$ink' }}
|
|
$group-focusVisible={{ color: '$ink' }}
|
|
>
|
|
<T values={{ name: f.name }}>{'Explore {name} →'}</T>
|
|
</Text>
|
|
</Leaf>
|
|
</YStack>
|
|
))}
|
|
</View>
|
|
</Grid>
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
export default Family
|