mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
The bar is Models, Dev, Platform, Pricing, Docs, Enterprise, Log in, and Get API key. The homepage is seven sections. Launch pages stay in the tree and drop out of the index through lib/launch.ts. /platform forwards to /cloud. Model and repository floors come from the snapshots the build already keeps. Co-authored-by: z <[email protected]>
321 lines
19 KiB
TypeScript
321 lines
19 KiB
TypeScript
"use client"
|
||
|
||
/**
|
||
* /press — the kit, the facts, and who to email.
|
||
*
|
||
* NO TAILWIND AND NO STYLE OBJECTS. The six section frames are
|
||
* `components/marketing/band`'s `Band` and `Head`; @hanzo/ui's marketing
|
||
* components carry the type and the controls (`Display`, `Lede`, `Title`,
|
||
* `Chip`, `Action`, `Leaf`); everything left is gui props over
|
||
* @hanzo/design's tokens.
|
||
*
|
||
* Four things the swap moves, each the shared shape winning over this page's
|
||
* own copy of it:
|
||
*
|
||
* - the section headings take `Title quiet` and the `h1` takes
|
||
* `Display`, so this page's type ladder is the site's rather than its own.
|
||
* - every control is `Action` at one of its two weights. That includes the
|
||
* Brand Guidelines button, which was a `<Button>` INSIDE a `<Link>` — a
|
||
* control nested in a control, which is one tab stop too many and reads to a
|
||
* screen reader as a button inside a link. It is one link now.
|
||
* - a press release row is `Leaf`, so the hover lives in one rule rather than
|
||
* a `group` on the row and a `group-hover:` on the title. The title
|
||
* BRIGHTENS on approach where it used to dim to `foreground/80`.
|
||
* - `logoAssets[].preview` held a Tailwind class name IN THE DATA, which is a
|
||
* utility no scan of this file's markup would ever find. It is the colour it
|
||
* was standing for.
|
||
*/
|
||
|
||
import { motion } from "@/components/motion"
|
||
import type { ReactNode } from "react"
|
||
import {
|
||
Download,
|
||
Mail,
|
||
ExternalLink,
|
||
FileText,
|
||
Palette,
|
||
Building2,
|
||
Users,
|
||
Phone,
|
||
ArrowRight,
|
||
Newspaper,
|
||
} from "lucide-react"
|
||
import { HanzoLogo } from "@hanzo/logo/react"
|
||
import { Box, Text, XStack, YStack } from '@hanzo/ui'
|
||
import { Grid } from '@hanzo/ui/grid'
|
||
import { Band, Head } from '@/components/marketing/band'
|
||
import { Glow } from '@/components/shared/Glow'
|
||
import { WORKSPACE } from '@hanzo/app/lib/host'
|
||
import { Action, Chip, Display, Lede, More, Title, Leaf, Lift, Line } from '@hanzo/ui/marketing'
|
||
import { mix } from '@hanzo/app/lib/mix'
|
||
|
||
/** The inks this page draws in. */
|
||
const INK = 'var(--foreground)'
|
||
const DIM = 'var(--muted-foreground)'
|
||
|
||
/** The entrance every block here makes as it scrolls in. */
|
||
const rise = (delay?: number) => (
|
||
<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={delay ? { delay } : undefined} />
|
||
)
|
||
|
||
/** The hairline tile this page sets everything in. */
|
||
const CARD = { p: 24, rounded: 'var(--radius-xl)', borderWidth: 1, borderColor: 'var(--border)', bg: mix('var(--secondary)', 50) } as const
|
||
|
||
/** A small grey line, on the leading its utility paired with `text-sm`. */
|
||
const Small = ({ mb, render = 'div', children }: { mb?: number; render?: 'div' | 'p'; children: ReactNode }) => (
|
||
<Line render={render} display="block" mb={mb} fontSize="$2" color={DIM} lineHeight="1.4286">
|
||
{children}
|
||
</Line>
|
||
)
|
||
|
||
/** A card's heading, at the size the browser gives an h3. */
|
||
const CardTitle = ({ mb, children }: { mb: number; children: ReactNode }) => (
|
||
<Text render="h3" display="block" mb={mb} fontWeight="600" color={INK}>
|
||
{children}
|
||
</Text>
|
||
)
|
||
|
||
/** A release row: `Leaf` with its edge drawn at rest and 24px inside. */
|
||
const RELEASE = { p: 24, borderColor: "var(--border)", bg: mix('var(--secondary)', 50) } as const
|
||
|
||
// FACTS A JOURNALIST CAN CHECK, and only those.
|
||
//
|
||
// "Employees 50+" and "Customers 10,000+" were here and neither is
|
||
// corroborated anywhere in this company — no headcount source, no customer
|
||
// count that any system reports. On a press page those two are worse than
|
||
// vague: they are the numbers that get quoted, and a reporter who repeats one
|
||
// is repeating something we made up. Founding year and the Techstars cohort
|
||
// are stated elsewhere on this site and are checkable; the entity is who the
|
||
// contract is with.
|
||
const companyFacts = [
|
||
{ label: "Founded", value: "2016" },
|
||
{ label: "Headquarters", value: "San Francisco, CA" },
|
||
{ label: "Entity", value: "Hanzo Industries Inc." },
|
||
{ label: "Backing", value: "Techstars ’17" },
|
||
]
|
||
|
||
const pressReleases = [
|
||
{ date: "February 27, 2026", title: "Hanzo Launches One API for Every Model — 100+ Models, Zero Markup", description: "The Hanzo AI API provides access to over 100 models from every major provider through a single API key with zero markup on third-party pricing.", link: "/blog" },
|
||
{ date: "February 27, 2026", title: "Hanzo Cloud Launches with 10-54% Lower Pricing Than Competitors", description: "Hanzo Cloud offers developer VMs starting at $5/mo with 2x the RAM of DigitalOcean at the same price, zero egress fees, and global multi-cloud routing.", link: "/blog" },
|
||
{ date: "February 27, 2026", title: "Hanzo Bot: Full-Stack AI Agent Hosting from $5/mo", description: "Deploy AI agents with built-in access to 100+ models, 260+ MCP tools, GPU compute, and multimodal capabilities — audio transcription 85% cheaper than OpenAI.", link: "/blog" },
|
||
{ date: "February 27, 2026", title: "Zen4 Coder 480B: The Largest Open-Source Code Model", description: "Zen4 Coder 480B MoE delivers frontier-class code generation with only 22B active parameters, available through the Hanzo AI API.", link: "/blog" },
|
||
{ date: "February 9, 2026", title: "Zen4 Model Family Launch — 14 Models from 600M to 480B Parameters", description: "Zoo Labs Foundation releases the Zen4 model family built on Mixture of Diverse Experts architecture, spanning chat, code, vision, and audio — served on the Hanzo AI API.", link: "/blog" },
|
||
{ date: "February 27, 2026", title: "Complete AI Pricing Breakdown: Models, Cloud, GPU, and Audio", description: "Every Hanzo rate in one place — gateway, cloud, GPU, and audio.", link: "/blog" },
|
||
]
|
||
|
||
const logoAssets = [
|
||
{ name: "Logo - Dark Background", description: "White logo for use on dark backgrounds", format: "SVG, PNG", preview: "var(--background)", logoColor: "white" },
|
||
{ name: "Logo - Light Background", description: "Black logo for use on light backgrounds", format: "SVG, PNG", preview: "var(--pure-white)", logoColor: "black" },
|
||
{ name: "Icon Only", description: "Standalone icon without wordmark", format: "SVG, PNG, ICO", preview: "var(--secondary)", logoColor: "white" },
|
||
] as const
|
||
|
||
const socialLinks = [
|
||
{ name: "Discord", handle: "discord.gg/XthHQQj", href: "https://discord.gg/XthHQQj" },
|
||
{ name: "X (Twitter)", handle: "@hanzoai", href: "https://x.com/hanzoai" },
|
||
{ name: "GitHub", handle: "@hanzoai", href: "https://github.com/hanzoai" },
|
||
{ name: "LinkedIn", handle: "hanzo-ai", href: "https://linkedin.com/company/hanzo-ai" },
|
||
{ name: "Facebook", handle: "@hanzoinc", href: "https://facebook.com/hanzoinc" },
|
||
{ name: "Bluesky", handle: "@hanzoai.bsky.social", href: "https://bsky.app/profile/hanzoai.bsky.social" },
|
||
{ name: "Reddit", handle: "r/HanzoAI", href: "https://www.reddit.com/r/HanzoAI/" },
|
||
{ name: "TikTok", handle: "@hanzoinc", href: "https://www.tiktok.com/@hanzoinc" },
|
||
{ name: "Instagram", handle: "@hanzoinc", href: "https://www.instagram.com/hanzoinc" },
|
||
]
|
||
|
||
const partnerAssets = [
|
||
{ name: "Techstars", files: [{ label: "Logo (PNG)", href: "/press/partners/techstars/techstars.png" }] },
|
||
{ name: "NVIDIA", files: [{ label: "Logo (SVG)", href: "/press/partners/nvidia/nvidia.svg" }] },
|
||
{ name: "Google Cloud", files: [{ label: "Logo (SVG)", href: "/press/partners/googlecloud/googlecloud.svg" }] },
|
||
{ name: "AWS", files: [{ label: "Logo (SVG)", href: "/press/partners/aws/aws.svg" }] },
|
||
{ name: "DigitalOcean", files: [{ label: "Logo (SVG)", href: "/press/partners/digitalocean/digitalocean.svg" }] },
|
||
{ name: "Nebius", files: [{ label: "Logo (SVG)", href: "/press/partners/nebius/nebius.svg" }] },
|
||
]
|
||
|
||
const LogoPreview = ({ isDark }: { isDark: boolean }) => (
|
||
<HanzoLogo variant={isDark ? "white" : "mono"} size={32} />
|
||
)
|
||
|
||
export default function PressPage() {
|
||
return (
|
||
<Box minH="100vh" $platform-web={{ color: INK }}>
|
||
<main>
|
||
{/* Hero */}
|
||
<Box
|
||
render="section"
|
||
position="relative"
|
||
overflow="hidden"
|
||
pt={96}
|
||
pb={64}
|
||
px={16}
|
||
$md={{ px: 32 }}
|
||
$lg={{ px: 48 }}
|
||
>
|
||
|
||
<Box position="relative" z="var(--z-raised)" width="100%" maxW={1024} mx="auto" $platform-web={{ textAlign: 'center' }}>
|
||
<Chip render={<motion.div initial={{ opacity: 0, y: 16 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4 }} />} mb={24} px={12} py={4} fontSize="$1" lineHeight="1.3333" fontWeight="500" borderColor="var(--border)" bg="var(--white-20)" color={INK}>
|
||
<Newspaper width={14} height={14} />Press & Media
|
||
</Chip>
|
||
<Display render={<motion.h1 initial={{ opacity: 0, y: 16 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4, delay: 0.05 }} />} mb={24}>
|
||
Press<br />Resources.
|
||
</Display>
|
||
<Lede render={<motion.p initial={{ opacity: 0, y: 16 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4, delay: 0.1 }} />} mb={40} width="100%" maxW={768} mx="auto">
|
||
Press kit, brand assets, and who to email — for anyone writing about Hanzo AI, Inc.
|
||
</Lede>
|
||
<XStack render={<motion.div initial={{ opacity: 0, y: 16 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4, delay: 0.15 }} />} flexWrap="wrap" items="center" justify="center" gap={16}>
|
||
<Action href="/press/hanzo-press-kit.zip" download fill><Download width={16} height={16} />Download Press Kit</Action>
|
||
<Action href="mailto:[email protected]"><Mail width={16} height={16} />Contact Press Team</Action>
|
||
</XStack>
|
||
</Box>
|
||
</Box>
|
||
|
||
{/* Company Overview */}
|
||
<Band rule={false} pad="$10" measure={1152} ground="linear-gradient(to bottom in oklab, var(--background), color-mix(in oklab, var(--neutral-900) 30%, transparent))">
|
||
<Box render={rise()} {...CARD} p={32}>
|
||
<XStack items="center" gap={12} mb={24}>
|
||
<XStack width={40} height={40} items="center" justify="center" rounded="var(--radius-lg)" bg="var(--white-10)"><Building2 width={20} height={20} color={INK} /></XStack>
|
||
<Title quiet>About Hanzo AI, Inc.</Title>
|
||
</XStack>
|
||
<Line render="p" display="block" mb={32} fontSize="$4" color={mix('var(--foreground)', 80)} lineHeight="var(--leading-relaxed)">Hanzo AI, Inc. is an AI technology company building the infrastructure for the next generation of intelligent applications. Founded in 2016 and headquartered in San Francisco, Hanzo is led by CEO Antje Worring and CTO Zach Kelling, providing AI platforms, developer tools, and cloud services to companies worldwide. Our mission is to make AI accessible, safe, and beneficial for everyone.</Line>
|
||
<Grid columns={{ min: 120, max: 4 }} gap={24}>
|
||
{companyFacts.map((fact) => (
|
||
<Box key={fact.label} p={16} rounded="var(--radius-lg)" bg={mix('var(--neutral-800)', 50)} $platform-web={{ textAlign: 'center' }}>
|
||
<Line render="div" display="block" mb={4} fontSize="$7" fontWeight="700" color={INK} lineHeight="1.3333">{fact.value}</Line>
|
||
<Small>{fact.label}</Small>
|
||
</Box>
|
||
))}
|
||
</Grid>
|
||
</Box>
|
||
</Band>
|
||
|
||
{/* Press Contact */}
|
||
<Band rule={false} pad="$10" measure={1152}>
|
||
<Head title="Press Contact" lede="Get in touch with our media relations team." />
|
||
<Grid columns={{ min: 320, max: 2 }} gap={24}>
|
||
<Box render={rise()} {...CARD}>
|
||
<CardTitle mb={16}>Media Inquiries</CardTitle>
|
||
<YStack gap={12}>
|
||
<More href="mailto:[email protected]"><Mail width={20} height={20} color={INK} />press@hanzo.ai</More>
|
||
<XStack items="center" gap={12} $platform-web={{ color: DIM }}><Phone width={20} height={20} color={INK} />+1 (424) 335-0550</XStack>
|
||
</YStack>
|
||
</Box>
|
||
<Box render={rise(0.1)} {...CARD}>
|
||
<CardTitle mb={16}>Headquarters</CardTitle>
|
||
<YStack gap={4} $platform-web={{ color: DIM }}>
|
||
<Text render="p" display="block" fontWeight="500" color={INK}>Hanzo AI, Inc.</Text>
|
||
<p>San Francisco, California</p>
|
||
<p>United States</p>
|
||
</YStack>
|
||
</Box>
|
||
</Grid>
|
||
</Band>
|
||
|
||
{/* Brand Assets */}
|
||
<Band rule={false} pad="$10" measure={1152} ground="color-mix(in oklab, var(--secondary) 30%, transparent)">
|
||
<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }}>
|
||
<YStack gap={16} mb={48} $md={{ flexDirection: 'row', items: 'center', justify: 'space-between' }}>
|
||
<Box>
|
||
<Title quiet mb={8}>Brand Assets</Title>
|
||
<Text render="p" display="block" color={DIM}>Download logos and visual assets.</Text>
|
||
</Box>
|
||
<Action href="/brand" self="flex-start"><FileText width={16} height={16} />Brand Guidelines</Action>
|
||
</YStack>
|
||
</motion.div>
|
||
<Grid columns={{ min: 280, max: 3 }} gap={24} mb={32}>
|
||
{logoAssets.map((asset, index) => (
|
||
<Box key={asset.name} render={rise(index * 0.1)} overflow="hidden" rounded="var(--radius-xl)" borderWidth={1} borderColor="var(--border)">
|
||
<XStack height={128} items="center" justify="center" bg={asset.preview}><LogoPreview isDark={asset.logoColor === "white"} /></XStack>
|
||
<Box p={16} bg={mix('var(--secondary)', 50)}>
|
||
<CardTitle mb={4}>{asset.name}</CardTitle>
|
||
<Small render="p" mb={8}>{asset.description}</Small>
|
||
<Line render="p" display="block" fontSize="$1" color={DIM} lineHeight="1.3333">{asset.format}</Line>
|
||
</Box>
|
||
</Box>
|
||
))}
|
||
</Grid>
|
||
<XStack render={rise()} flexWrap="wrap" gap={16}>
|
||
<Action href="/press/hanzo-press-kit.zip" fill><Download width={16} height={16} />Download Press Kit (ZIP)</Action>
|
||
<Action href="/brand"><Palette width={16} height={16} />View Brand Guidelines</Action>
|
||
</XStack>
|
||
<Box mt={40}>
|
||
<Line render="h3" display="block" mb={16} fontSize="$4" fontWeight="600" color={INK} lineHeight="1.5556">Partner Assets</Line>
|
||
<Grid columns={{ min: 280, max: 3 }} gap={16}>
|
||
{partnerAssets.map((partner) => (
|
||
<Box key={partner.name} p={16} rounded="var(--radius-xl)" borderWidth={1} borderColor="var(--border)" bg={mix('var(--secondary)', 40)}>
|
||
<Line render="div" display="block" mb={8} fontSize="$2" textTransform="uppercase" color={DIM} lineHeight="1.4286" letterSpacing="0.1em">{partner.name}</Line>
|
||
<YStack gap={8}>
|
||
{partner.files.map((file) => (
|
||
<More key={file.href} href={file.href || "#"}><ExternalLink width={16} height={16} />{file.label}</More>
|
||
))}
|
||
</YStack>
|
||
</Box>
|
||
))}
|
||
</Grid>
|
||
</Box>
|
||
</Band>
|
||
|
||
{/* Recent News */}
|
||
<Band rule={false} pad="$10" measure={1152}>
|
||
<Head title="Recent News" lede="Latest press releases and company announcements." />
|
||
<YStack gap={16}>
|
||
{pressReleases.map((release, index) => (
|
||
<motion.div key={release.title} initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ delay: index * 0.1 }}>
|
||
<Leaf href={release.link || "#"} {...RELEASE}>
|
||
<XStack items="flex-start" justify="space-between" gap={16}>
|
||
<Box>
|
||
<Small mb={8}>{release.date}</Small>
|
||
<Lift render="h3" display="block" mb={8} fontWeight="600">{release.title}</Lift>
|
||
<Small render="p">{release.description}</Small>
|
||
</Box>
|
||
{/* The resting ink rides the wrapper so the lift can still
|
||
reach the mark. `Lift step` is the slide — the site's
|
||
one step, read off the link this mark sits in. */}
|
||
<Line display="inline-flex" shrink={0} color={mix('var(--muted-foreground)', 60)}>
|
||
<Lift display="inline-flex" step><ArrowRight width={20} height={20} /></Lift>
|
||
</Line>
|
||
</XStack>
|
||
</Leaf>
|
||
</motion.div>
|
||
))}
|
||
</YStack>
|
||
</Band>
|
||
|
||
{/* Social Media */}
|
||
<Band rule={false} pad="$10" measure={1152} ground="color-mix(in oklab, var(--secondary) 30%, transparent)">
|
||
<Head title="Connect With Us" lede="Follow us on social media for the latest updates." />
|
||
<Grid columns={{ min: 150, max: 5 }} gap={16}>
|
||
{socialLinks.map((social, index) => (
|
||
<Box
|
||
key={social.name}
|
||
render={<motion.a href={social.href || "#"} target="_blank" rel="noopener noreferrer" initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ delay: index * 0.05 }} />}
|
||
p={16}
|
||
rounded="var(--radius-xl)"
|
||
borderWidth={1}
|
||
borderColor="var(--border)"
|
||
bg={mix('var(--secondary)', 50)}
|
||
$platform-web={{ textAlign: 'center' }}
|
||
>
|
||
<Text render="div" display="block" mb={4} fontWeight="600" color={INK}>{social.name}</Text>
|
||
<Small>{social.handle}</Small>
|
||
</Box>
|
||
))}
|
||
</Grid>
|
||
</Band>
|
||
|
||
{/* CTA */}
|
||
<Band rule={false} pad="$12" measure={896} ground="linear-gradient(to bottom in oklab, color-mix(in oklab, var(--neutral-900) 30%, transparent), var(--background))">
|
||
<Glow corner="top" pct={10} />
|
||
<Glow corner="bottom" pct={5} />
|
||
<Box position="relative" z="var(--z-raised)" $platform-web={{ textAlign: 'center' }}>
|
||
<Chip render={<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} />} mb={24} px={12} py={4} fontSize="$1" lineHeight="1.3333" fontWeight="500" borderColor="var(--border)" bg="var(--white-20)" color={INK}><Users width={14} height={14} />Leadership</Chip>
|
||
<Title render={<motion.h2 initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} />} quiet mb={16}>Meet our team</Title>
|
||
<Lede render={<motion.p initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ delay: 0.1 }} />} mb={40} width="100%" maxW={672} mx="auto" mt="$3.5">For executive bios and headshots, visit our team page or contact our press team.</Lede>
|
||
<XStack render={rise(0.2)} flexWrap="wrap" items="center" justify="center" gap={16}>
|
||
<Action href={WORKSPACE} fill>View Team<ArrowRight width={20} height={20} /></Action>
|
||
<Action href="mailto:[email protected]">Request Executive Bios</Action>
|
||
</XStack>
|
||
</Box>
|
||
</Band>
|
||
</main>
|
||
</Box>
|
||
)
|
||
}
|