Files
hanzo.ai/components/zap/ZapHero.tsx

134 lines
5.0 KiB
TypeScript

'use client'
/**
* NO TAILWIND. Layout is gui props, type is @hanzo/ui's marketing roles
* (`Display`, `Claim`, `Lede`, `Chip`, `Action`) and the band kit's `Words`, over
* @hanzo/design's tokens.
*/
import React from "react";
import { motion } from "@/components/motion";
import { Zap, ArrowRight } from "lucide-react";
import { Box, View, XStack } from '@hanzo/ui'
import { Words } from '@/components/marketing/band'
import { Grid as Columns } from '@hanzo/ui/grid'
import { Action, Chip, Claim, Display, Lede } from '@hanzo/ui/marketing'
/** `Chip` leaves the padding and the fill to its caller. */
const BADGE = { mb: 32, px: 16, py: 8, borderColor: "var(--border)", bg: "color-mix(in oklab, var(--pure-white) 5%, transparent)" } as const
/** The ink the badge and the figures share: the foreground at 70%. */
const SOFT = 'color-mix(in oklab, var(--foreground) 70%, transparent)'
/** One figure under the lede: the number, and what it means. */
function Stat({ value, label }: { value: string; label: string }) {
return (
<Box rounded="var(--radius-xl)" borderWidth={1} borderColor="var(--border)" background="color-mix(in oklab, var(--secondary) 50%, transparent)" p={16}>
<Words render="div" fontSize="$7" lineHeight="1.3333" weight="700" color={SOFT}>{value}</Words>
<Words render="div" fontSize="$2" lineHeight="1.4286" color="var(--muted-foreground)">{label}</Words>
</Box>
)
}
/** The first control carries a faint fill; the other two are the bare outline. */
const FILLED = { px: 32, bg: "color-mix(in oklab, var(--pure-white) 10%, transparent)", color: "var(--primary-foreground)" } as const
const OUTLINED = { px: 32, borderColor: "var(--border)" } as const
const ZapHero = () => {
return (
<XStack
render="section"
position="relative"
items="center"
justify="center"
overflow="hidden"
minH="90vh"
py={80}
px={16}
$sm={{ px: 24 }}
$lg={{ px: 32 }}
>
{/* Animated background */}
<Box position="relative" z="var(--z-raised)" width="100%" maxW={1024} mx="auto" $platform-web={{ textAlign: 'center' }}>
{/* Badge */}
<Chip
render={<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} />}
{...BADGE}
>
<Zap width={16} height={16} color={SOFT} />
<Words fontSize="$2" lineHeight="1.4286" weight="500" color={SOFT}>Zero-Copy Agent Protocol</Words>
</Chip>
{/* Headline */}
<Display
render={<motion.h1 initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.1 }} />}
mb={24}
>
ZAP
</Display>
<Claim
render={<motion.p initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.15 }} />}
mb={16}
fontWeight="500"
color="var(--foreground)"
>
The wire format is the data structure
</Claim>
<Lede
render={<motion.p initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.2 }} />}
mb={32}
maxW={768}
mx="auto"
>
ZAP is the Zero-copy Application Protocol — binary RPC between services, with a sixteen-byte header
and a data segment laid out so a reader walks it where it landed. There is no parse step to skip,
because there is nothing to parse. MCP, A2A and ACP all ride on it unchanged, so you keep the
protocol your stack already speaks.
</Lede>
{/* Stats */}
<View
render={<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.25 }} />}
display="block"
mb={48}
maxW={768}
mx="auto"
>
<Columns columns={{ min: 160, max: 4 }} gap={16}>
<Stat value="No parse" label="Read it where it landed" />
<Stat value="16 bytes" label="The whole header" />
<Stat value="Go · Rust · TS" label="One wire, three readers" />
<Stat value="MCP · A2A · ACP" label="All run on ZAP" />
</Columns>
</View>
{/* CTAs */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.3 }}
>
<XStack flexWrap="wrap" justify="center" gap={16}>
<Action href="https://zap-proto.dev/docs/quick-start" {...FILLED}>
Read the docs
<ArrowRight width={16} height={16} />
</Action>
<Action href="https://github.com/zap-proto/papers" {...OUTLINED}>
Read the Papers
</Action>
<Action href="https://github.com/zap-proto/spec" {...OUTLINED}>
GitHub
</Action>
</XStack>
</motion.div>
</Box>
</XStack>
);
};
export default ZapHero;