Files
zeekayandGitHub 949608fd9d i18n: pages and components c–l draw their copy through @hanzo/i18n (#67)
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
2026-10-30 01:15:31 -07:00

92 lines
2.6 KiB
TypeScript

'use client'
import type { ReactNode } from 'react'
import { ArrowRight } from 'lucide-react'
import { useI18n } from '@hanzo/i18n/react'
import { Box, XStack } from '@hanzo/ui'
import { Action, More } from '@hanzo/ui/marketing'
import { Fold } from '@/components/marketing/fold'
import { LOGIN } from '@hanzo/app/lib/destination'
/**
* The opening of a model family's page — /kai, /dev, /gen, /kata and a model's
* own page: the first screen (components/marketing/fold) with 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, beside the family's figure.
*/
export function Hero({
trail,
chip,
title,
lede,
action,
figure,
primary,
more,
below,
points,
stage,
}: {
/** The crumbs over a deep page: a model's own, under its lab. */
trail?: ReactNode
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: a model card's links. */
below?: ReactNode
/** What it does, three or four short lines (Fold `points`). */
points?: string[]
/** The figure is an app's demo: on a phone it is the first screen (Fold `stage`). */
stage?: boolean
}) {
const { t } = useI18n()
return (
<Fold
top={trail}
label={chip}
title={title}
lede={lede}
points={points}
stage={stage}
actions={
<>
<Action href={primary?.href ?? LOGIN} fill>
{t(primary?.label ?? 'Try Hanzo')} <ArrowRight size={16} data-i18n-mirror />
</Action>
<Action href={action.href}>{t(action.label)}</Action>
</>
}
below={
more || below ? (
<>
{more ? <More href={more.href}>{t(more.label)}</More> : null}
{below}
</>
) : undefined
}
preview={figure}
/>
)
}
/** The one line a family page keeps about the other two: where they are compared. */
export function Siblings({ name }: { name: string }) {
const { t } = useI18n()
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">
{t('{name} is one of three Hanzo model families. Compare them →', { name })}
</More>
</XStack>
</Box>
)
}