mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
The product pages from /s3 to /zap, /university and its course data, /trust, /security, /sdks, /support, /tasks, /startups, /sms-opt-in, the buying specialist, Zen, Kai's guide, Studio, the settings pages, and the shared sales, solutions, zap and ui pieces. Client code draws with t(), server components with <T>, copy held as data is marked with phrase() and drawn through t() where it lands. A link or a figure inside a sentence is a value, so a translator reorders the whole sentence. Rebased on main: every page main moved onto Fold or Steps keeps main's layout, with its words wrapped (label, title, lede, points). Steps now draws a step's body through t, as it already drew the title. Settings keeps main's usage panel, refresh, rewards wallet and sign-in wallet rows, each label wrapped. Left English: the skills page's install line (a command and two URLs), and the solution eyebrow and sibling heading built from a kind label. Claude-Session: https://claude.ai/code/session_015XYKLjZtDTJEnMo4eK3AFH
101 lines
3.9 KiB
TypeScript
101 lines
3.9 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* NO TAILWIND. The two washes are siblings of the measure rather than children
|
|
* of it — each is sized against the SECTION, so a `Band` (which centres its
|
|
* children on a measure) is the wrong frame here and the section is stated
|
|
* outright, the same way `components/operator/OperativeHero` states its own.
|
|
*
|
|
* Type is the roles in `app/globals.css`: `pill`, `title`, `lede`, `action`.
|
|
*/
|
|
|
|
import React from "react";
|
|
import { motion } from "@/components/motion";
|
|
import { ArrowRight, Zap, BookOpen } from "lucide-react"
|
|
import { Github } from "@/components/brand"
|
|
import { Box, XStack, YStack } from '@hanzo/ui'
|
|
import { Words } from '@/components/marketing/band'
|
|
import { Action, Chip, Lede, Title } from '@hanzo/ui/marketing'
|
|
import { useI18n } from '@hanzo/i18n/react'
|
|
|
|
const WASH = {
|
|
position: 'absolute',
|
|
width: 384,
|
|
height: 384,
|
|
rounded: 'var(--radius-full)',
|
|
background: 'color-mix(in oklab, var(--pure-white) 5%, transparent)',
|
|
filter: 'blur(64px)',
|
|
} as const
|
|
|
|
/** The ink the badge and the second line share: the foreground at 70%. */
|
|
const SOFT = 'color-mix(in oklab, var(--foreground) 70%, transparent)'
|
|
|
|
/** `Chip` leaves the padding and the fill to its caller. */
|
|
const BADGE = { self: "center", mb: 32, px: 16, py: 8, borderColor: "var(--border)", bg: "color-mix(in oklab, var(--pure-white) 5%, transparent)" } as const
|
|
|
|
const FILLED = { px: 32, py: 16, bg: "color-mix(in oklab, var(--pure-white) 10%, transparent)", color: "var(--primary-foreground)" } as const
|
|
|
|
const OUTLINED = { px: 32, py: 16, borderColor: "var(--border)" } as const
|
|
|
|
|
|
const ZapCTA = () => {
|
|
const { t } = useI18n();
|
|
return (
|
|
<YStack
|
|
render="section"
|
|
position="relative"
|
|
overflow="hidden"
|
|
py={80}
|
|
px={16}
|
|
$sm={{ px: 24 }}
|
|
$lg={{ px: 32 }}
|
|
>
|
|
{/* Background decorations */}
|
|
<Box {...WASH} t={0} l="25%" />
|
|
<Box {...WASH} b={0} r="25%" />
|
|
|
|
<Box position="relative" z="var(--z-raised)" width="100%" maxW={896} mx="auto" $platform-web={{ textAlign: 'center' }}>
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.5 }}
|
|
>
|
|
<Chip {...BADGE}>
|
|
<Zap width={16} height={16} color={SOFT} />
|
|
<Words fontSize="$2" lineHeight="1.4286" weight="500" color={SOFT}>Go · Rust · TypeScript</Words>
|
|
</Chip>
|
|
|
|
<Title quiet mb={24} color="var(--foreground)">
|
|
{t('Point one agent at it')}
|
|
</Title>
|
|
|
|
<Lede mb={32} maxW={672} mx="auto" mt="$3.5">
|
|
{t('Start the daemon, add the MCP servers you already run, change one address in your agent.')}
|
|
<br />
|
|
<Words color={SOFT}>{t('Nothing else about your setup has to move.')}</Words>
|
|
</Lede>
|
|
|
|
<XStack flexWrap="wrap" justify="center" gap={16}>
|
|
<Action href="https://zap-proto.dev/docs" {...FILLED}>
|
|
<BookOpen width={20} height={20} />
|
|
{t('Read the docs')}
|
|
<ArrowRight width={16} height={16} data-i18n-mirror />
|
|
</Action>
|
|
<Action href="https://github.com/zap-proto/spec" {...OUTLINED}>
|
|
<Github width={20} height={20} />
|
|
{t('View on GitHub')}
|
|
</Action>
|
|
</XStack>
|
|
|
|
<Words render="p" mt={48} mx="auto" maxW={576} fontSize="$1" lineHeight="1.3333" color="var(--muted-foreground)">
|
|
{t('What ZAP saves depends on your workload, your payload size and your topology. The claim here is about mechanism, not about a number: a reader that walks the buffer in place does no parsing and no allocation, and shared backends run one process where per-agent sidecars run many. Measure it on your own traffic — we have not published a benchmark and will not quote one we cannot show you.')}
|
|
</Words>
|
|
</motion.div>
|
|
</Box>
|
|
</YStack>
|
|
);
|
|
};
|
|
|
|
export default ZapCTA;
|