Files
zeekay ac64d5d7dd Folds say one line: every first screen keeps its heading and a single lede
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.
2026-10-30 06:42:40 -07:00

577 lines
24 KiB
TypeScript

"use client"
/**
* /careers — the openings, the terms, and how hiring runs.
*
* NO TAILWIND. The four 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`, `Line`); everything
* left is gui props over @hanzo/design's tokens.
*/
import { useState, useEffect, type FormEvent } from "react"
import { motion } from "@/components/motion"
import {
Briefcase,
Globe,
Clock,
MapPin,
Users,
Sparkles,
ArrowRight,
Heart,
CheckCircle2,
X,
Share2,
Check,
ExternalLink,
} from "lucide-react"
import { Box, Button, Dialog, DialogContent, DialogTitle, Input, Text, Textarea, View, XStack, YStack } from '@hanzo/ui'
import { Grid } from '@hanzo/ui/grid'
import { Band, Head } from '@/components/marketing/band'
import { Fold } from '@/components/marketing/fold'
import { Steps } from '@/components/preview/steps'
import { Action, Lede, Title, Leaf, Lift, Line, type LineProps } from '@hanzo/ui/marketing'
import { api } from '@hanzo/app/lib/api'
import { track } from '@hanzo/app/lib/tags'
import { jobOpenings, getJobOpening, type JobOpening } from '@/lib/careers'
import { shownCareer } from '@/lib/launch'
import { ResumeAndConsent, resumeProblem, uploadResume } from './apply'
import { phrase } from '@hanzo/i18n'
import { useI18n } from '@hanzo/i18n/react'
/** The two inks this page draws body copy in. */
const INK = 'var(--foreground)'
const DIM = 'var(--muted-foreground)'
/** The pair of controls that closes a section, wrapping on a phone. */
const ROW = { flexWrap: 'wrap', items: 'center', justify: 'center', gap: 16 } as const
/** The hairline tile, centred. */
const CARD = { rounded: 'var(--radius-xl)', borderWidth: 1, borderColor: 'var(--border)', bg: 'var(--secondary)', p: 24 } as const
/** A card's heading and the paragraph under it. */
const CardTitle = (p: LineProps) => (
<Line render="h3" display="block" mb={8} fontSize="$4" lineHeight="1.5556" fontWeight="600" color={INK} {...p} />
)
const CardBody = (p: LineProps) => (
<Line render="p" display="block" fontSize="$2" lineHeight="1.4286" color={DIM} {...p} />
)
/** A job card's own frame: `Leaf` with its edge drawn at rest and 24px inside. */
const OPENING = { p: 24, borderColor: "var(--border)", bg: "var(--secondary)" } as const
/** An icon on a tinted tile — the mark that opens a card. */
const TILE = {
width: 48,
height: 48,
items: 'center',
justify: 'center',
rounded: 'var(--radius-lg)',
'$platform-web': { backgroundColor: 'color-mix(in oklab, var(--pure-white) 10%, transparent)' },
} as const
/** The one fact line beside a job: a mark and a word. */
const Fact = (p: LineProps) => (
<Line display="inline-flex" items="center" gap={4} whiteSpace="normal" fontSize="$2" lineHeight="1.4286" color={DIM} {...p} />
)
const benefits = [
{ icon: Globe, title: phrase("Remote-first"), description: phrase("The team is distributed. Work from wherever you already live.") },
{ icon: Clock, title: phrase("Your own hours"), description: phrase("We care what you ship, not what time you were online.") },
{ icon: Users, title: phrase("Small team"), description: phrase("Few enough people that you own whole systems rather than tickets.") },
{ icon: Sparkles, title: phrase("The work is public"), description: phrase("Most of what we build is open source, under your own name.") },
]
const hiringSteps = [
{ step: "1", title: phrase("Application Review"), description: phrase("We review your resume and application materials") },
{ step: "2", title: phrase("Initial Interview"), description: phrase("Get to know you and your experience") },
{ step: "3", title: phrase("Technical Assessment"), description: phrase("Showcase your skills (no whiteboarding)") },
{ step: "4", title: phrase("Final Interview"), description: phrase("Meet the team and discuss next steps") },
]
/** An address as https: one typed without a scheme gets https://, and cloud drops any other. */
const https = (u: string): string => {
const t = u.trim()
return !t || /^[a-z][a-z0-9+.-]*:/i.test(t) ? t : `https://${t}`
}
export default function CareersPage() {
const { t } = useI18n()
const [activeJob, setActiveJob] = useState<JobOpening | null>(null)
const [copiedId, setCopiedId] = useState<string | null>(null)
const [form, setForm] = useState({
name: '',
email: '',
github: '',
linkedin: '',
location: '',
resume: '',
notes: '',
})
const [file, setFile] = useState<File | null>(null)
const [consent, setConsent] = useState(false)
const [busy, setBusy] = useState(false)
const [sent, setSent] = useState(false)
const [wrong, setWrong] = useState<string | null>(null)
useEffect(() => {
if (typeof window === 'undefined') return
const params = new URLSearchParams(window.location.search)
const applyId = params.get('apply')
if (applyId) {
const match = getJobOpening(applyId)
if (match) setActiveJob(match)
}
}, [])
const openApply = (job: JobOpening) => {
setActiveJob(job)
setSent(false)
setWrong(null)
if (typeof window !== 'undefined') {
history.pushState(null, '', `?apply=${job.id}`)
}
}
const closeApply = () => {
setActiveJob(null)
setSent(false)
setWrong(null)
if (typeof window !== 'undefined') {
const url = new URL(window.location.href)
url.searchParams.delete('apply')
history.pushState(null, '', url.pathname + (url.hash || ''))
}
}
const copyRoleLink = (jobId: string, e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()
if (typeof window !== 'undefined') {
const origin = window.location.origin
navigator.clipboard.writeText(`${origin}/careers/${jobId}`)
setCopiedId(jobId)
setTimeout(() => setCopiedId(null), 2000)
}
}
const handleSubmit = async (e: FormEvent) => {
e.preventDefault()
if (busy) return
if (!form.name.trim() || !form.email.trim() || !form.notes.trim()) {
setWrong(t('Please fill in your name, email, and cover note / background.'))
return
}
const EMAIL_TEST = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!EMAIL_TEST.test(form.email.trim())) {
setWrong(t('Please enter a valid email address.'))
return
}
if (file && resumeProblem(file)) {
setWrong(t(resumeProblem(file)))
return
}
setWrong(null)
setBusy(true)
let resumeFile = ''
try {
if (file) resumeFile = await uploadResume(file)
} catch {
setWrong(t('Your resume did not upload. Please try again, or give a link instead.'))
setBusy(false)
return
}
const payload = {
name: form.name.trim(),
email: form.email.trim(),
role: activeJob?.title || 'Open Application',
department: activeJob?.department || 'General',
country: form.location.trim() || activeJob?.location || 'Remote',
source: `hanzo.ai/careers/${activeJob?.id || 'open'}`,
// An application to an opening is a candidate in the CRM (cloud apps/marketing
// leads.go `job`): what the person wrote, their resume and their links, with no
// call offered and nothing sent to the ad platforms.
job: activeJob?.id || 'open',
need: form.notes.trim(),
resume: https(form.resume),
links: [https(form.github), https(form.linkedin)].filter(Boolean),
resume_file: resumeFile,
consent,
}
try {
const r = await fetch(`${api()}/v1/marketing/leads`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
if (!r.ok) throw new Error(`HTTP ${r.status}`)
track('career_application_submitted', { role: payload.role, department: payload.department, slug: activeJob?.id })
setSent(true)
} catch (err) {
track('career_application_submitted', { role: payload.role, department: payload.department, slug: activeJob?.id, error: String(err) })
setWrong(t('Your application did not reach us. Please try again, or email it to {email}.', { email: '[email protected]' }))
} finally {
setBusy(false)
}
}
return (
<Box minH="100vh" $platform-web={{ color: INK }}>
<main>
<Fold
label="Careers"
mark={<Heart width={14} height={14} color="currentColor" aria-hidden />}
title={t('Compilers, cryptography,{br}and the cloud they run on.', { br: <br /> })}
lede="Hanzo is a small team building an open AI cloud — the inference engine, the models, the backend services, and the agents that use them."
actions={
<>
<Action href="#open-positions" fill>
{t('View Open Positions')}
<ArrowRight width={16} height={16} />
</Action>
<Action href="/about">
{t('Read the history')}
</Action>
</>
}
preview={<Steps title="How we hire" icon={<Briefcase size={12} color="currentColor" />} steps={hiringSteps.map((h) => ({ title: h.title, body: h.description }))} />}
/>
{/* Benefits Section */}
<Band rule={false} pad="$10" measure={1152} ground="color-mix(in oklab, var(--secondary) 20%, transparent)">
<Head title={t('Benefits & Perks')} lede={t('How the team actually works.')} />
<Grid columns={{ min: 260, max: 4 }} gap={24}>
{benefits.map((benefit, index) => {
const Icon = benefit.icon
return (
<Box
key={benefit.title}
render={<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ delay: index * 0.1 }} />}
{...CARD}
$platform-web={{ textAlign: 'center' }}
>
<XStack mb={16} mx="auto" {...TILE}>
<Icon width={24} height={24} color={INK} />
</XStack>
<CardTitle>{t(benefit.title)}</CardTitle>
<CardBody>{t(benefit.description)}</CardBody>
</Box>
)
})}
</Grid>
</Band>
{/* Open Positions Section */}
<Band id="open-positions" rule={false} pad="$10" measure={1152}>
<Head title={t('Open Positions')} lede={t('Remote, unless the work needs hardware in a room.')} />
<Grid columns={{ min: 320, max: 2 }} gap={24}>
{jobOpenings.filter((job) => shownCareer(job.id)).map((job, index) => (
<Leaf
id={job.id}
render={<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ delay: index * 0.05 }} />}
key={job.id}
{...OPENING}
>
<XStack items="flex-start" gap={16}>
<XStack shrink={0} {...TILE}>
<Briefcase width={24} height={24} color={INK} />
</XStack>
<YStack grow={1} shrink={1} flexBasis="0%">
<XStack items="center" justify="space-between" mb={8} gap={8}>
<Line href={`/careers/${job.id}`} color="inherit" whiteSpace="inherit">
<Lift render="h3" display="block" fontSize="$6" lineHeight="1.4" fontWeight="700">
{t(job.title)}
</Lift>
</Line>
<Line
render="button"
type="button"
onClick={(e) => copyRoleLink(job.id, e)}
title={t('Copy direct link to this position')}
display="inline-flex"
items="center"
p={4}
color={copiedId === job.id ? 'var(--primary)' : DIM}
>
{copiedId === job.id ? <Check size={16} /> : <Share2 size={16} />}
</Line>
</XStack>
<XStack gap={12} mb={12} flexWrap="wrap">
<Fact><MapPin width={16} height={16} /> {t(job.location)}</Fact>
<Fact><Clock width={16} height={16} /> {t(job.type)}</Fact>
<Fact><Users width={16} height={16} /> {t(job.department)}</Fact>
</XStack>
<CardBody mb={16}>{t(job.description)}</CardBody>
<XStack gap={12} flexWrap="wrap" items="center">
<Action
href={`/careers/${job.id}`}
onClick={(e) => {
e.preventDefault()
openApply(job)
}}
fill
self="flex-start"
>
{t('Apply for this role')}
<ArrowRight width={16} height={16} data-i18n-mirror />
</Action>
<Action
href={`/careers/${job.id}`}
self="flex-start"
>
{t('View Details')}
<ExternalLink width={14} height={14} />
</Action>
</XStack>
</YStack>
</XStack>
</Leaf>
))}
</Grid>
<Box render={<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} />} mt={32} $platform-web={{ textAlign: 'center' }}>
<Line render="p" display="block" mb={16} color={DIM}>
{t("Don't see a position that fits your skills?")}
</Line>
<Action
href="/careers/open"
onClick={(e) => {
e.preventDefault()
const openRole = getJobOpening('open')
if (openRole) openApply(openRole)
}}
>
{t('Submit Open Application')}
</Action>
</Box>
</Band>
{/* CTA Section */}
<Band rule={false} pad="$12" measure={896}>
<View
position="absolute"
t={-160}
r={-160}
width={320}
height={320}
rounded="var(--radius-full)"
filter="blur(64px)"
pointerEvents="none"
$platform-web={{ backgroundColor: 'color-mix(in oklab, var(--pure-white) 10%, transparent)' }}
/>
<View
position="absolute"
b={-160}
l={-160}
width={320}
height={320}
rounded="var(--radius-full)"
filter="blur(64px)"
pointerEvents="none"
$platform-web={{ backgroundColor: 'color-mix(in oklab, var(--pure-white) 5%, transparent)' }}
/>
<Box position="relative" z="var(--z-raised)" $platform-web={{ textAlign: 'center' }}>
<Title render={<motion.h2 initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} />} quiet mb={16}>{t('Ready to join us?')}</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">
{t('If you have read the codebase and had opinions about it, we want to hear them.')}
</Lede>
<XStack render={<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ delay: 0.2 }} />} {...ROW}>
<Action href="#open-positions" fill>
{t('Browse Open Positions')}
<ArrowRight width={20} height={20} data-i18n-mirror />
</Action>
<Action href="mailto:[email protected]">
careers@hanzo.ai
</Action>
</XStack>
</Box>
</Band>
<Dialog open={Boolean(activeJob)} onOpenChange={(o) => (!o ? closeApply() : undefined)}>
<DialogContent
showCloseButton={false}
width="calc(100vw - 32px)"
maxW={540}
rounded="$6"
p="$5"
gap="$4"
bg="var(--secondary)"
borderWidth={1}
borderColor="var(--border)"
>
<XStack items="center" justify="space-between" width="100%">
<YStack gap="$1">
<DialogTitle fontSize="$6" fontWeight="700" color={INK}>
{sent ? t('Application Received') : activeJob ? t(activeJob.title) : undefined}
</DialogTitle>
{!sent && activeJob ? (
<Text fontSize="$2" color={DIM}>
{t(activeJob.department)} · {t(activeJob.location)} · {t(activeJob.type)}
</Text>
) : null}
</YStack>
<XStack
render="button"
aria-label={t('Close')}
p="$1.5"
rounded="$3"
hoverStyle={{ bg: 'var(--white-06)' }}
cursor="pointer"
onPress={closeApply}
>
<X size={18} color={INK} />
</XStack>
</XStack>
{sent ? (
<YStack gap="$4" py="$4" items="center">
<CheckCircle2 size={48} color="var(--primary)" />
<YStack gap="$2" items="center">
<Text fontSize="$4" fontWeight="600" color={INK}>
{t('Thank you for applying!')}
</Text>
<Text fontSize="$2" color={DIM} maxW={420} $platform-web={{ textAlign: 'center' }}>
{t('Your application for {role} has been submitted to our team. We review submissions promptly and will reach out to {email}.', {
role: <Text fontWeight="600" color={INK}>{activeJob ? t(activeJob.title) : undefined}</Text>,
email: <Text fontWeight="600" color={INK}>{form.email}</Text>,
})}
</Text>
<Text fontSize="$1" color={DIM} mt="$2" $platform-web={{ textAlign: 'center' }}>
{t('You can also email additional materials or portfolio samples directly to {email}.', {
email: (
<Text render="a" {...{ href: `mailto:[email protected]?subject=${encodeURIComponent(`Application: ${activeJob?.title} - ${form.name}`)}` }} color="var(--primary)" textDecorationLine="underline">
careers@hanzo.ai
</Text>
),
})}
</Text>
</YStack>
<Button variant="primary" onPress={closeApply} mt="$2">
{t('Done')}
</Button>
</YStack>
) : (
<YStack render="form" {...{ onSubmit: handleSubmit }} width="100%" gap={14}>
<YStack gap="$1">
<Text fontSize="$2" fontWeight="500" color={INK}>
{t('Full Name')} <Text render="span" color="var(--destructive)">*</Text>
</Text>
<Input
value={form.name}
onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
placeholder="Ada Lovelace"
required
/>
</YStack>
<YStack gap="$1">
<Text fontSize="$2" fontWeight="500" color={INK}>
{t('Work Email')} <Text render="span" color="var(--destructive)">*</Text>
</Text>
<Input
type="email"
value={form.email}
onChange={(e) => setForm((f) => ({ ...f, email: e.target.value }))}
placeholder="[email protected]"
required
/>
</YStack>
<XStack gap="$3" flexWrap="wrap">
<YStack flex={1} minW={200} gap="$1">
<Text fontSize="$2" fontWeight="500" color={INK}>
{t('GitHub / Portfolio')}
</Text>
<Input
value={form.github}
onChange={(e) => setForm((f) => ({ ...f, github: e.target.value }))}
placeholder="https://github.com/..."
/>
</YStack>
<YStack flex={1} minW={200} gap="$1">
<Text fontSize="$2" fontWeight="500" color={INK}>
{t('LinkedIn / Website')}
</Text>
<Input
value={form.linkedin}
onChange={(e) => setForm((f) => ({ ...f, linkedin: e.target.value }))}
placeholder="https://linkedin.com/in/..."
/>
</YStack>
</XStack>
<YStack gap="$1">
<Text fontSize="$2" fontWeight="500" color={INK}>
{t('Resume link')}
</Text>
<Input
value={form.resume}
onChange={(e) => setForm((f) => ({ ...f, resume: e.target.value }))}
placeholder={t('A link to your resume: PDF, Google Drive or Dropbox')}
/>
</YStack>
<ResumeAndConsent file={file} onFile={setFile} consent={consent} onConsent={setConsent} />
<YStack gap="$1">
<Text fontSize="$2" fontWeight="500" color={INK}>
{t('Location / Timezone')}
</Text>
<Input
value={form.location}
onChange={(e) => setForm((f) => ({ ...f, location: e.target.value }))}
placeholder={t('e.g. San Francisco, CA or Remote (UTC-8)')}
/>
</YStack>
<YStack gap="$1">
<Text fontSize="$2" fontWeight="500" color={INK}>
{t('Background & Why Hanzo')} <Text render="span" color="var(--destructive)">*</Text>
</Text>
<Textarea
value={form.notes}
onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}
placeholder={t("Briefly tell us what systems you've built, open source work, or what interests you about our cloud and models.")}
rows={4}
required
/>
</YStack>
{wrong ? (
<Text fontSize="$2" color="var(--destructive)">
{wrong}
</Text>
) : null}
<XStack justify="space-between" items="center" mt="$2">
<Text
render="a"
{...{ href: `mailto:[email protected]?subject=${encodeURIComponent(`Application: ${activeJob?.title}`)}` }}
fontSize="$1"
color="var(--muted-foreground)"
textDecorationLine="underline"
>
{t('Or email resume directly')}
</Text>
<XStack gap="$2">
<Button variant="ghost" size="sm" type="button" onPress={closeApply}>
{t('Cancel')}
</Button>
<Button variant="primary" size="sm" type="submit" disabled={busy}>
{busy ? t('Submitting…') : t('Submit Application')}
</Button>
</XStack>
</XStack>
</YStack>
)}
</DialogContent>
</Dialog>
</main>
</Box>
)
}