Files
hanzo.ai/components/home/Questions.tsx
zeekay 0f5536b707 hanzo.ai reads in the reader's language, and Arabic right to left
Every word the landing, the header menus, the phone sheet, the footer,
the help corner and the way in (sign-in, sign-up, the reset, the
invitation, the callback, onboarding, the 404) write goes through
@hanzo/i18n's t(): one sentence is one message, its figures, names and
links arguments; copy written as data is phrase('…') where written and
t(label) where drawn. Plans, the chart, the API states and the lines
lib/kai and lib/enso build for the landing do the same.

Right to left: <html lang dir> is set before the first paint (the
package's bootScript first in the head); a figure, clock, range or
price outside a sentence is isolated; sides are logical gui props, the
layout's [data-join] corners logical, a bar grows from the start;
arrows along the line mirror (Onward for "words ->" links). The repo
dates read in the reader's language.

Gates select by slot, never by an English label (rtl, help). New gate
translated.spec.ts: in Arabic the landing at 1440 and 390, every menu
open, the phone sheet, sign-in, sign-up and the app signed in hold no
authored English, nothing scrolls sideways, every range is isolated;
French the same for English's commonest words. What another package
draws with no words prop is listed by name (@hanzo/ui's Footer label,
@hanzo/build's composer row and suggestions).

@hanzo/i18n 0.5.3 (the catalogs: 1,443 keys, every offered locale
complete), @hanzo/app 0.2.1 (the app's words). The link gate imports
the terms versions from @hanzo/app, the one SDK main now resolves.
2026-10-22 19:54:31 -07:00

82 lines
3.7 KiB
TypeScript

'use client'
import type { ReactNode } from 'react'
import { useAnalytics } from '@hanzo/event/react'
import { YStack } from '@hanzo/gui'
import { phrase, translate } from '@hanzo/i18n'
import { useI18n, type Say } from '@hanzo/i18n/react'
import { Faq, TextLink } from '@hanzo/ui/marketing'
import { FaqJsonLd, plain } from '@/components/marketing/FaqJsonLd'
/**
* The questions a stranger arrives with on the landing, answered against what
* Hanzo ships today. No price and no plan name is written here: the plans above
* draw both from the catalog, and an answer that names one is a second copy
* that goes stale (scripts/audit-price-literals.mjs).
*
* Each question is a phrase and each answer is drawn by the `t` it is handed:
* the reader's language on the page, and `english` for the structured copy
* (FaqJsonLd), which speaks for the English export to a crawler whatever the
* reader chose.
*/
const FAQ: readonly { q: string; a: (t: Say) => ReactNode }[] = [
{
q: phrase('What is Hanzo and how does it work?'),
a: (t) =>
t(
'Hanzo is an AI cloud on one account. Chat with frontier models, build and ship with Hanzo Dev, and call the same models from one API: Enso, our frontier model, and Kai, which makes a decision in one call. {link}.',
{ link: <TextLink href="/platform">{t('How the platform fits together')}</TextLink> },
),
},
{
q: phrase('Can I keep using Claude Code?'),
a: (t) =>
t(
'Yes. Install the Hanzo CLI and sign in, then run Claude Code with its model calls going through api.hanzo.ai, or point your own Claude Code install at Hanzo. The commands are at the top of this page, ready to copy.',
),
},
{
q: phrase('Where do the numbers on this page come from?'),
a: (t) =>
t(
"Each one is read when the page opens: the race and the boards from Hanzo's research runs, the prices from our price list, and the plans from our plan list. A figure whose source does not answer is left out, never replaced with an older one. {link}.",
{ link: <TextLink href="/benchmarks">{t('Every board and its runs')}</TextLink> },
),
},
{
q: phrase('How much does it cost to use?'),
a: (t) =>
t(
'Free needs no card. Paid plans are sold by the month for one person and by the member for a team, and every paid plan can be cancelled any time. Enterprise is priced with our team. {link}.',
{ link: <TextLink href="/pricing">{t('See every plan and model rate')}</TextLink> },
),
},
{
q: phrase('Can Hanzo run in our own cloud or on our own GPUs?'),
a: (t) =>
t('Yes, with Enterprise: in your cloud, on your own servers or fully offline, with dedicated compute and your own models. {link}.', {
link: <TextLink href="/enterprise">Hanzo Enterprise</TextLink>,
}),
},
]
/** A message as written, its arguments read down to their words: the answers in the English the structured copy carries. */
const english: Say = (source: string, values: Readonly<Record<string, ReactNode>> = {}) =>
translate({}, source, Object.fromEntries(Object.entries(values).map(([k, v]) => [k, plain(v)])))
export default function Questions() {
const { t } = useI18n()
const events = useAnalytics()
return (
<YStack width="100%" py={56} $md={{ py: 80 }}>
<FaqJsonLd path="/" items={FAQ.map((f) => ({ name: f.q, answer: f.a(english) }))} />
<Faq
heading={t('FAQ')}
items={FAQ.map((f) => ({ q: t(f.q), a: f.a(t) }))}
// The event names the question as written, in whichever language it was read.
onOpen={(q) => events.capture('faq_opened', { q: FAQ.find((f) => t(f.q) === q)?.q ?? q })}
/>
</YStack>
)
}