mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
The owner's spec for a landing page is the models bento's: monochrome, the words left and the art right, no extra prose. The folds carried two to four sentences under each heading, and some a claim, a lede and a list besides. Each now says one line: ProductLanding the tagline where a page states one (the lede still describes it to search), a claim alone where the claim is the line (/payments, /treasury, /zap, the extension), and elsewhere the sentence that says what the thing is. /philosophy's two points, /dns' claim that repeated its title, /calculator's capabilities line and the Spare clauses on /research and /learn go.
74 lines
3.2 KiB
TypeScript
74 lines
3.2 KiB
TypeScript
'use client'
|
|
|
|
import { YStack } from '@hanzo/gui'
|
|
import { Action } from '@hanzo/ui/marketing'
|
|
import { Fold } from '@/components/marketing/fold'
|
|
import { Grid } from '@hanzo/ui/grid'
|
|
import { useI18n } from '@hanzo/i18n/react'
|
|
|
|
import { SurfaceCard } from '@/components/download/surface-card'
|
|
import { LEAD, REST } from '@/data/downloads'
|
|
|
|
/**
|
|
* Every way to get Hanzo, on one page.
|
|
*
|
|
* THE PAGE IS HERE, and it is the only copy. It stood on hanzo.app and this
|
|
* route was a shell that forwarded to it — which held only while that host
|
|
* served the page itself. hanzo.app answers with a redirect now: its root sends
|
|
* a reader here and every other path to the builder, so a forward from this
|
|
* route arrived back at /dev and the download page could not be reached in a
|
|
* browser at all. A page that two hosts point at is a page with no home.
|
|
*
|
|
* A surface appears iff a READER can act on it. The builds come from
|
|
* `data/releases.json`, which `scripts/sync-releases.mjs` resolves anonymously
|
|
* against the real releases on every build, so a platform that publishes
|
|
* nothing — or publishes only where the public cannot reach — stops rendering
|
|
* rather than becoming a button that 404s. There is deliberately no mobile
|
|
* card: no iOS or Android build has shipped to either store, and a tile that
|
|
* apologises for itself occupies the place of a product. `data/downloads.ts`
|
|
* carries both measurements.
|
|
*
|
|
* The chrome is the marketing layout's, which draws the header and footer for
|
|
* every page in this group, and the title comes from `layout.tsx` beside this
|
|
* file — so this file is the content and nothing else.
|
|
*/
|
|
export default function DownloadPage() {
|
|
const { t } = useI18n()
|
|
return (
|
|
<>
|
|
{/* The first screen: the promise over the lead surface, its builds, its install line and the agent running. */}
|
|
<Fold
|
|
label={t('Download')}
|
|
title={t('Get Hanzo everywhere you work.')}
|
|
lede={t('Install the coding agent, open the workspaces that need nothing installed, and sign in to all of them the same way.')}
|
|
actions={
|
|
<>
|
|
<Action href="#surfaces" fill>
|
|
{t('Every way to get it')}
|
|
</Action>
|
|
<Action href="https://docs.hanzo.ai/docs/quickstart">{t('The quickstart')}</Action>
|
|
</>
|
|
}
|
|
>
|
|
<YStack width="100%" maxW={1152} mx="auto">
|
|
<SurfaceCard surface={LEAD} lead />
|
|
</YStack>
|
|
</Fold>
|
|
<YStack id="surfaces" px="$4" pt="$8" pb="$10" $md={{ px: '$6', pt: '$10' }}>
|
|
{/* `width="100%"` is load-bearing on a centred column: without it
|
|
`alignSelf="center"` is shrink-to-fit and `maxWidth` caps a width the
|
|
column never takes, which reads as a section that is silently narrow. */}
|
|
<YStack self="center" width="100%" maxW={1152} gap="$8">
|
|
{/* auto-fit rather than auto-fill: the row is a fixed set of surfaces,
|
|
so a survivor stretches across the empty track instead of leaving it. */}
|
|
<Grid columns="repeat(auto-fit, minmax(min(460px, 100%), 1fr))" gap={20} items="flex-start">
|
|
{REST.map((s) => (
|
|
<SurfaceCard key={s.id} surface={s} />
|
|
))}
|
|
</Grid>
|
|
</YStack>
|
|
</YStack>
|
|
</>
|
|
)
|
|
}
|