mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
82 lines
2.8 KiB
TypeScript
82 lines
2.8 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* The surface every `/blockchain` page is drawn on, stated once: the three
|
|
* inks, the hairline tile, the disc a mark sits on, and a card's two lines.
|
|
*
|
|
* Four pages under this route each declared their own copy of these and they
|
|
* had drifted — the disc was `pure-white` at 10% on three and at 5% on the
|
|
* fourth. A value with four homes is four values wearing one name.
|
|
*
|
|
* The grounds are token mixes, which gui's colour type does not take, so they
|
|
* ride `$platform-web`; everything else is a prop.
|
|
*/
|
|
import type { ComponentProps, ReactNode } from 'react'
|
|
import { Box, Text, XStack } from '@hanzo/ui'
|
|
|
|
/** The three strengths of the foreground these pages draw in. */
|
|
export const INK = 'var(--foreground)'
|
|
export const DIM = 'var(--muted-foreground)'
|
|
/** A share of the foreground. */
|
|
export const ink = (pct: number) => `color-mix(in oklab, var(--foreground) ${pct}%, transparent)`
|
|
export const SOFT = ink(80)
|
|
|
|
/** A share of pure white, for a disc, an edge or a wash. */
|
|
export const white = (pct: number) => `color-mix(in oklab, var(--pure-white) ${pct}%, transparent)`
|
|
|
|
/** The ground the tiles sit on: the secondary surface at half strength. */
|
|
export const GROUND = 'color-mix(in oklab, var(--secondary) 50%, transparent)'
|
|
|
|
/** The hairline tile these pages set everything in. Padding is the caller's. */
|
|
export function Card({ children, ...p }: { children?: ReactNode } & ComponentProps<typeof Box>) {
|
|
return (
|
|
<Box
|
|
rounded="var(--radius-xl)"
|
|
borderWidth={1}
|
|
borderColor="var(--border)"
|
|
{...p}
|
|
$platform-web={{ backgroundColor: GROUND, ...p['$platform-web'] }}
|
|
>
|
|
{children}
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
/** The disc a mark sits on, at the size the caller states. */
|
|
export function Tile({ size, children, ...p }: { size: number; children?: ReactNode } & ComponentProps<typeof XStack>) {
|
|
return (
|
|
<XStack
|
|
width={size}
|
|
height={size}
|
|
shrink={0}
|
|
items="center"
|
|
justify="center"
|
|
rounded="var(--radius-lg)"
|
|
{...p}
|
|
$platform-web={{ backgroundColor: white(10), ...p['$platform-web'] }}
|
|
>
|
|
{children}
|
|
</XStack>
|
|
)
|
|
}
|
|
|
|
type TextProps = ComponentProps<typeof Text>
|
|
|
|
/** A card's name: the browser's h3 rung, on the page's 20px line. */
|
|
export function CardTitle({ children, ...p }: { children: ReactNode } & Omit<TextProps, 'children'>) {
|
|
return (
|
|
<Text render="h3" display="block" mb={4} fontSize={16.38} lineHeight="1.25rem" fontWeight="600" color={INK} {...p}>
|
|
{children}
|
|
</Text>
|
|
)
|
|
}
|
|
|
|
/** The paragraph under a card's name. */
|
|
export function CardBody({ children, ...p }: { children: ReactNode } & Omit<TextProps, 'children'>) {
|
|
return (
|
|
<Text render="p" display="block" fontSize="$2" lineHeight="1.1607rem" color={DIM} {...p}>
|
|
{children}
|
|
</Text>
|
|
)
|
|
}
|