Files
zeekayandGitHub e20dc71ad8 i18n: /s* to /z*, the app's rooms and settings read their copy through t (#69)
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
2026-10-29 23:51:44 -07:00

103 lines
3.5 KiB
TypeScript

'use client'
/**
* The e-signing plans, as a band of the product page they sit on.
*
* Same frame, same reasons, as `components/captable/Pricing.tsx` — read that
* file for the three moves this one also makes (`FADE` for the ground, the
* `Title` role for the heading, and the `{ min: 240, max: 4 }` deck that
* wraps on width rather than at `md` and `lg`).
*/
import PricingPlan from "@/components/pricing/PricingPlan";
import { PenLine, Building2, Rocket } from "lucide-react"
import { Github } from "@/components/brand"
import { Grid } from '@hanzo/ui/grid'
import { Band, Head, FADE } from '@/components/marketing/band'
import { phrase } from '@hanzo/i18n'
import { useI18n } from '@hanzo/i18n/react'
/** Every tier's mark, at the size and ink components/pricing draws them. */
const MARK = { size: 24, color: 'var(--muted-foreground)' } as const
const Pricing = () => {
const { t } = useI18n()
return (
<Band rule={false} pad="$10" measure={1152} ground={FADE}>
<Head
title={t('What it costs')}
lede={t('Run it yourself and pay nothing but your own hosting. Pay us and we run it, on the same code.')}
/>
<Grid columns={{ min: 240, max: 4 }} gap={24}>
<PricingPlan
name={phrase('Community')}
icon={<Github {...MARK} />}
price={phrase('Free')}
description={phrase('Self-host and own your data. Full source code on GitHub.')}
githubLink
features={[
phrase('Unlimited documents'),
phrase('All field types'),
phrase('Templates'),
phrase('API access'),
phrase('Email notifications'),
phrase('Community support'),
]}
/>
<PricingPlan
name={phrase('Starter')}
icon={<PenLine {...MARK} />}
price="$30"
billingPeriod={phrase('/mo')}
description={phrase('For individuals and small teams getting started with e-signing.')}
features={[
phrase('Everything in Community'),
phrase('Managed cloud hosting'),
phrase('Custom branding'),
phrase('Priority email support'),
phrase('Signing certificates'),
phrase('5 team members'),
]}
/>
<PricingPlan
name={phrase('Business')}
icon={<Building2 {...MARK} />}
price="$50"
billingPeriod={phrase('/mo')}
popular
description={phrase('For growing teams that need advanced features and integrations.')}
features={[
phrase('Everything in Starter'),
phrase('Unlimited team members'),
phrase('Custom domain'),
phrase('Advanced templates'),
phrase('Webhooks'),
phrase('SAML SSO'),
phrase('Audit logs'),
phrase('Priority support'),
]}
/>
<PricingPlan
name={phrase('Enterprise')}
icon={<Rocket {...MARK} />}
price={phrase('Custom')}
description={phrase('For organizations with advanced security and compliance needs.')}
contactSalesUrl="/contact-sales"
features={[
phrase('Everything in Business'),
phrase('Dedicated infrastructure'),
phrase('Custom SLA'),
phrase('On-premise deployment'),
phrase('Compliance certifications'),
phrase('Dedicated account manager'),
phrase('24/7 phone support'),
]}
/>
</Grid>
</Band>
);
};
export default Pricing;