Files
hanzo.ai/components/oss/OSSRevenueBanner.tsx

158 lines
5.6 KiB
TypeScript

'use client'
/**
* The open-source royalty banner, in its two weights — a one-line strip and a
* full card. The number is apps/author's: a verified author earns 20% of the
* metered spend of every org that deploys a project built from their
* repository. /oss says how.
*
* Layout is gui props, type is `Line` (the one ramp, so `text-sm` here means
* what it means everywhere), and the controls are the site's own shapes from
* `app/globals.css`: `Action` is THE button, at its two weights, and
* `More` is the quiet link. Those rules exist because this pill had already
* been written out as the same eight utilities in seven places and drifted;
* these were two more of them. Everything with an ink of its own — the tinted
* badge — stays in gui props, because a role class states a colour too and
* wearing one to get a shape then means arguing it back out.
*
* `justify-content` is stated inline on the actions because `Action` is
* `inline-flex` and the column that holds them stretches its items, so without
* it the label packs to the left edge of a stretched pill.
*/
import { motion } from '@/components/motion'
import { ArrowRight, Link2, GitFork } from 'lucide-react'
import { View, XStack, YStack } from '@hanzo/ui'
import { Line } from '@/components/type'
import { Action, More } from '@hanzo/ui/marketing'
/** `bg-secondary/30` and its neighbours, spelt as the colour they already were. */
const tint = (token: string, pct: number) => `color-mix(in oklab, var(${token}) ${pct}%, transparent)`
/** An action is centred in the pill even when the column stretches it. */
const CENTRED = { justify: "center" } as const
export function OSSRevenueBanner({ compact = false }: { compact?: boolean }) {
if (compact) {
return (
<motion.div
initial={{ opacity: 0, y: 10 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4 }}
>
<YStack width="100%" maxW={1024} mx="auto" px="$4" py="$4">
<XStack
flexWrap="wrap"
items="center"
justify="space-between"
gap="$3"
borderWidth={1}
borderColor="var(--border)"
rounded="var(--radius-lg)"
bg="$hover"
px="$4"
py="$3"
>
<XStack render="p" items="center" gap="$2" flex={1} minW={0}>
<View render={<Link2 size={16} color="var(--foreground)" />} shrink={0} />
<Line render="span" size="sm" color="var(--muted-foreground)" minW={0}>
A verified author earns 20% of the metered spend of every deploy built
from their repository.
</Line>
</XStack>
<More href="/oss" whiteSpace="nowrap">
How it works
<ArrowRight size={14} />
</More>
</XStack>
</YStack>
</motion.div>
)
}
return (
<motion.section
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5 }}
>
<YStack
py="$10"
px="$4"
$sm={{ px: '$5' }}
$lg={{ px: '$6' }}
>
<YStack width="100%" maxW={1024} mx="auto">
<YStack
borderWidth={1}
borderColor="var(--border)"
rounded="var(--radius-xl)"
p="$5"
$md={{ p: '$6' }}
background={`linear-gradient(to right, ${tint('--secondary', 30)}, ${tint('--secondary', 10)})`}
>
<YStack gap="$5" $md={{ flexDirection: 'row', items: 'center' }}>
{/* Left content */}
<YStack flex={1}>
<XStack
display="inline-flex"
self="flex-start"
items="center"
gap="$2"
mb="$4"
px="$3"
py="$1"
borderWidth={1}
borderColor="var(--border)"
rounded="var(--radius-full)"
bg="$panel"
>
<GitFork size={14} color="var(--foreground)" />
<Line render="span" size="xs" weight="500" caps color={tint('--foreground', 80)}>
Open source royalty
</Line>
</XStack>
<Line
render="h3"
size="xl"
weight="700"
marginBottom="$2"
$md={{ fontSize: '$7', lineHeight: '1.3333' }}
>
20% to the author of the code that runs
</Line>
<Line
render="p"
size="sm"
color="var(--muted-foreground)"
$md={{ fontSize: '$3', lineHeight: '1.5' }}
>
Verify that you own a repository, and every org that deploys a project
built from it pays you 20% of its metered spend, accrued each period.
</Line>
</YStack>
{/* Right buttons */}
<YStack gap="$3" shrink={0} $sm={{ flexDirection: 'row' }} $md={{ flexDirection: 'column' }}>
<Action href="/oss" fill {...CENTRED}>
How authors are paid
<ArrowRight size={16} />
</Action>
<Action href="/open-source" {...CENTRED}>
Our repositories
</Action>
</YStack>
</YStack>
</YStack>
</YStack>
</YStack>
</motion.section>
)
}
export default OSSRevenueBanner