@orangecheck/app-design 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brand.d.mts +26 -4
- package/dist/brand.d.ts +26 -4
- package/dist/brand.js +342 -49
- package/dist/brand.js.map +1 -1
- package/dist/brand.mjs +341 -50
- package/dist/brand.mjs.map +1 -1
- package/dist/components.d.mts +43 -2
- package/dist/components.d.ts +43 -2
- package/dist/components.js +206 -0
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +200 -1
- package/dist/components.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +547 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +539 -50
- package/dist/index.mjs.map +1 -1
- package/dist/styles/motion.css +52 -0
- package/dist/styles/tokens.css +2 -0
- package/package.json +1 -1
package/dist/brand.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/cn.ts","../src/brand/mark.tsx","../src/brand/sphere.tsx","../src/brand/iso-check.tsx","../src/brand/crowd.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"brand.mjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n// tailwind-merge would treat `oca-display-1` and `text-foreground` as the same\n// group and drop one; teach it the package's own type utilities.\nconst merge = extendTailwindMerge<'oca-type'>({\n extend: {\n classGroups: {\n 'oca-type': [\n 'oca-display-1',\n 'oca-display-2',\n 'oca-display-3',\n 'oca-title',\n 'oca-title-sm',\n 'oca-eyebrow',\n 'oca-lead',\n 'oca-body',\n 'oca-numeral',\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]): string {\n return merge(clsx(inputs));\n}\n","import type { SVGProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/*\n * The isometric check, measured from Sou's deck (slide 9) onto a 16×8 grid:\n * a chevron with a 3-unit short arm and a 5-unit long arm, one unit thick,\n * extruded two units. Three faces, three oranges.\n */\n\nconst TOP = '0,3 2,2 6,4 14,0 16,1 6,6';\nconst LEFT = '0,3 6,6 6,8 0,5';\nconst RIGHT = '6,6 16,1 16,3 6,8';\n\nexport const MARK_FACES = { top: '#FED8AB', left: '#FB933C', right: '#EA580B' } as const;\n\nexport interface MarkProps extends Omit<SVGProps<SVGSVGElement>, 'children'> {\n /** Accessible name. Omit to render the mark as decoration. */\n title?: string;\n /** Rendered width in px; height follows the 2:1 grid. */\n size?: number;\n}\n\nexport function Mark({ title, size, className, ...rest }: MarkProps) {\n return (\n <svg\n viewBox=\"0 0 16 8\"\n width={size}\n height={size ? size / 2 : undefined}\n role={title ? 'img' : undefined}\n aria-hidden={title ? undefined : true}\n className={cn('shrink-0', className)}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n <polygon points={LEFT} fill={MARK_FACES.left} />\n <polygon points={RIGHT} fill={MARK_FACES.right} />\n <polygon points={TOP} fill={MARK_FACES.top} />\n </svg>\n );\n}\n\nexport interface AppIconProps extends Omit<SVGProps<SVGSVGElement>, 'children'> {\n title?: string;\n size?: number;\n}\n\n/** The app icon: the mark on an ink squircle, as in the deck's lockup. */\nexport function AppIcon({ title, size = 32, className, ...rest }: AppIconProps) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n role={title ? 'img' : undefined}\n aria-hidden={title ? undefined : true}\n className={cn('shrink-0', className)}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n <rect\n width=\"24\"\n height=\"24\"\n rx=\"6.25\"\n style={{ fill: 'var(--oca-icon-tile, #0A0A0A)', stroke: 'var(--oca-icon-ring, transparent)' }}\n strokeWidth=\"0.5\"\n />\n <g transform=\"translate(4.25 8.1) scale(0.97)\">\n <polygon points={LEFT} fill={MARK_FACES.left} />\n <polygon points={RIGHT} fill={MARK_FACES.right} />\n <polygon points={TOP} fill={MARK_FACES.top} />\n </g>\n </svg>\n );\n}\n\nexport interface LockupProps {\n /** The word beside the icon. */\n name?: string;\n /** Icon size in px; the word scales with it. */\n size?: number;\n className?: string;\n}\n\n/** Icon and wordmark, lowercase, as the deck sets it. */\nexport function Lockup({ name = 'orangecheck', size = 28, className }: LockupProps) {\n return (\n <span\n className={cn('inline-flex items-center font-medium tracking-[-0.01em]', className)}\n style={{ gap: size * 0.32, fontSize: size * 0.56 }}\n >\n <AppIcon size={size} />\n <span>{name}</span>\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/*\n * The deck's photograph: a halftone portrait on an orange ball, lit from the\n * upper left, with a hairline stadium behind it. The dot layer is an image of\n * black dots on transparent, made by scripts/halftone.py, so the ball stays CSS\n * and the dots stay crisp at any size.\n */\n\nexport const SPHERE_GRADIENT =\n 'radial-gradient(86% 86% at 36% 32%, #fff7f0 0%, #ffdec8 14%, #ffa069 34%, #ff7030 56%, #f65210 78%, #de4006 100%)';\n\nconst SPHERE_DEPTH = 'inset -14px -22px 44px rgb(150 40 0 / 0.16), 0 36px 70px -34px rgb(234 88 11 / 0.45)';\n\nexport interface HalftoneSphereProps {\n /** The dot layer (black dots on transparent, already circular). */\n src: string;\n /** Describe the person or subject; empty string marks it decorative. */\n alt: string;\n /** Draw the hairline stadium behind the sphere, as the hero does. */\n stadium?: boolean;\n /** Let the sphere drift a few pixels. Off under reduced motion. */\n float?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nfunction Ball({ src, alt, float }: { src: string; alt: string; float: boolean }) {\n return (\n <div\n className={cn('relative size-full overflow-hidden rounded-full', float && 'oca-animate-float')}\n style={{ background: SPHERE_GRADIENT, boxShadow: SPHERE_DEPTH }}\n >\n {/* eslint-disable-next-line @next/next/no-img-element -- a static dot layer, sized by CSS */}\n <img src={src} alt={alt} className=\"absolute inset-0 size-full select-none\" draggable={false} />\n </div>\n );\n}\n\nexport function HalftoneSphere({ src, alt, stadium = false, float = false, className, style }: HalftoneSphereProps) {\n if (!stadium) {\n return (\n <div className={cn('relative aspect-square w-full', className)} style={style}>\n <Ball src={src} alt={alt} float={float} />\n </div>\n );\n }\n // Measured from the deck's title slide against the ball's width S: the stadium\n // starts 0.255 S left of and 0.127 S above the ball, is 1.11 S wide, and ends\n // level with its foot. Both live inside this box, so nothing reaches the text.\n return (\n <div className={cn('relative aspect-[1.255/1.127] w-full', className)} style={style}>\n <div aria-hidden className=\"oca-stadium pointer-events-none absolute left-0 top-0 h-full w-[88.4%] rounded-[32%]\" />\n <div className=\"absolute bottom-0 right-0 aspect-square w-[79.7%]\">\n <Ball src={src} alt={alt} float={float} />\n </div>\n </div>\n );\n}\n","import { cn } from '../lib/cn';\nimport { Mark } from './mark';\n\nexport interface IsoCheckProps {\n /** Width in px; the check keeps its 2:1 grid. */\n size?: number;\n /** Drop it into place on first paint, the deck's closing gesture. */\n settle?: boolean;\n /** A soft floor shadow, so it reads as an object on the canvas. */\n shadow?: boolean;\n title?: string;\n className?: string;\n}\n\n/** The isometric check as an object: the deck's closing illustration. */\nexport function IsoCheck({ size = 360, settle = false, shadow = true, title, className }: IsoCheckProps) {\n return (\n <div className={cn('relative inline-block', settle && 'oca-animate-settle', className)} style={{ width: size }}>\n <Mark size={size} title={title} className=\"relative z-10 block\" />\n {shadow ? (\n <div\n aria-hidden\n className=\"absolute left-[8%] right-[8%] rounded-[50%] opacity-60 blur-xl\"\n style={{ height: size * 0.08, bottom: -size * 0.04, background: 'rgb(234 88 11 / 0.18)' }}\n />\n ) : null}\n </div>\n );\n}\n","import { cn } from '../lib/cn';\n\n/*\n * \"A bot farm can pretend to be a crowd\": a crowd of identical figures in\n * perspective, nearer rows larger, with a few real ones in orange. Identical on\n * purpose: copies are what a bot farm is. Positions come from a fixed seed so\n * server and client draw the same crowd.\n */\n\nexport interface CrowdProps {\n cols?: number;\n rows?: number;\n /** How many figures are real (orange). */\n real?: number;\n seed?: number;\n /** Ground it sits on: figures are light on ink, dark on canvas. */\n tone?: 'ink' | 'canvas';\n /** Spoken by screen readers. */\n label?: string;\n className?: string;\n}\n\nconst CELL_W = 22;\nconst CELL_H = 27;\n\nfunction picks(count: number, total: number, seed: number): Set<number> {\n let s = seed >>> 0;\n const out = new Set<number>();\n while (out.size < Math.min(count, total)) {\n s = (Math.imul(s, 1664525) + 1013904223) >>> 0;\n out.add(s % total);\n }\n return out;\n}\n\nexport function Crowd({\n cols = 26,\n rows = 9,\n real = 7,\n seed = 21,\n tone = 'ink',\n label = 'A crowd of identical accounts. Only a few are real.',\n className,\n}: CrowdProps) {\n const width = cols * CELL_W;\n const scales = Array.from({ length: rows }, (_, r) => 0.5 + 0.5 * (r / Math.max(1, rows - 1)));\n const height = scales.reduce((h, s) => h + CELL_H * s, 0);\n // Real figures only in the nearer half, where they are big enough to see.\n const nearFrom = Math.floor(rows / 2) * cols;\n const realSet = new Set([...picks(real, rows * cols - nearFrom, seed)].map((i) => i + nearFrom));\n const bot = tone === 'ink' ? '#ffffff' : '#0a0a0a';\n let y = 0;\n return (\n <svg\n role=\"img\"\n aria-label={label}\n viewBox={`0 0 ${width} ${Math.ceil(height)}`}\n className={cn('block h-auto w-full', className)}\n >\n {scales.map((s, r) => {\n const rowY = y;\n y += CELL_H * s;\n const rowW = cols * CELL_W * s;\n const x0 = (width - rowW) / 2;\n return Array.from({ length: cols }, (_, c) => {\n const i = r * cols + c;\n const isReal = realSet.has(i);\n return (\n <g\n key={i}\n transform={`translate(${x0 + c * CELL_W * s} ${rowY}) scale(${s})`}\n fill={isReal ? 'var(--oca-orange)' : bot}\n fillOpacity={isReal ? 1 : 0.1 + 0.16 * s}\n >\n <circle cx={11} cy={8} r={4.4} />\n <path d=\"M3 25a8 8.5 0 0 1 16 0Z\" />\n </g>\n );\n });\n })}\n </svg>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/cn.ts","../src/brand/mark.tsx","../src/brand/portrait-tone.ts","../src/brand/halftone-canvas.tsx","../src/brand/sphere.tsx","../src/brand/iso-check.tsx","../src/brand/crowd.tsx"],"names":["jsxs","jsx","useRef","useEffect"],"mappings":"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","file":"brand.mjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n// tailwind-merge would treat `oca-display-1` and `text-foreground` as the same\n// group and drop one; teach it the package's own type utilities.\nconst merge = extendTailwindMerge<'oca-type'>({\n extend: {\n classGroups: {\n 'oca-type': [\n 'oca-display-1',\n 'oca-display-2',\n 'oca-display-3',\n 'oca-title',\n 'oca-title-sm',\n 'oca-eyebrow',\n 'oca-lead',\n 'oca-body',\n 'oca-numeral',\n ],\n },\n },\n});\n\nexport function cn(...inputs: ClassValue[]): string {\n return merge(clsx(inputs));\n}\n","import type { SVGProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/*\n * The isometric check, measured from Sou's deck (slide 9) onto a 16×8 grid:\n * a chevron with a 3-unit short arm and a 5-unit long arm, one unit thick,\n * extruded two units. Three faces, three oranges.\n */\n\nconst TOP = '0,3 2,2 6,4 14,0 16,1 6,6';\nconst LEFT = '0,3 6,6 6,8 0,5';\nconst RIGHT = '6,6 16,1 16,3 6,8';\n\nexport const MARK_FACES = { top: '#FED8AB', left: '#FB933C', right: '#EA580B' } as const;\n\nexport interface MarkProps extends Omit<SVGProps<SVGSVGElement>, 'children'> {\n /** Accessible name. Omit to render the mark as decoration. */\n title?: string;\n /** Rendered width in px; height follows the 2:1 grid. */\n size?: number;\n}\n\nexport function Mark({ title, size, className, ...rest }: MarkProps) {\n return (\n <svg\n viewBox=\"0 0 16 8\"\n width={size}\n height={size ? size / 2 : undefined}\n role={title ? 'img' : undefined}\n aria-hidden={title ? undefined : true}\n className={cn('shrink-0', className)}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n <polygon points={LEFT} fill={MARK_FACES.left} />\n <polygon points={RIGHT} fill={MARK_FACES.right} />\n <polygon points={TOP} fill={MARK_FACES.top} />\n </svg>\n );\n}\n\nexport interface AppIconProps extends Omit<SVGProps<SVGSVGElement>, 'children'> {\n title?: string;\n size?: number;\n}\n\n/** The app icon: the mark on an ink squircle, as in the deck's lockup. */\nexport function AppIcon({ title, size = 32, className, ...rest }: AppIconProps) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n role={title ? 'img' : undefined}\n aria-hidden={title ? undefined : true}\n className={cn('shrink-0', className)}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n <rect\n width=\"24\"\n height=\"24\"\n rx=\"6.25\"\n style={{ fill: 'var(--oca-icon-tile, #0A0A0A)', stroke: 'var(--oca-icon-ring, transparent)' }}\n strokeWidth=\"0.5\"\n />\n <g transform=\"translate(4.25 8.1) scale(0.97)\">\n <polygon points={LEFT} fill={MARK_FACES.left} />\n <polygon points={RIGHT} fill={MARK_FACES.right} />\n <polygon points={TOP} fill={MARK_FACES.top} />\n </g>\n </svg>\n );\n}\n\nexport interface LockupProps {\n /** The word beside the icon. */\n name?: string;\n /** Icon size in px; the word scales with it. */\n size?: number;\n className?: string;\n}\n\n/** Icon and wordmark, lowercase, as the deck sets it. */\nexport function Lockup({ name = 'orangecheck', size = 28, className }: LockupProps) {\n return (\n <span\n className={cn('inline-flex items-center font-medium tracking-[-0.01em]', className)}\n style={{ gap: size * 0.32, fontSize: size * 0.56 }}\n >\n <AppIcon size={size} />\n <span>{name}</span>\n </span>\n );\n}\n","/*\n * The deck portrait as ink, 128 × 128, one byte per cell (0 = paper, 255 = full\n * ink), read from the red channel so the orange ground is paper. Generated from\n * the deck's sphere by scripts/halftone.py's tone step; HalftoneCanvas screens\n * it live.\n */\nexport const PORTRAIT_TONE_SIZE = 128;\nexport const PORTRAIT_TONE_B64 =\n 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAADCKz/v//9lYBgAAAAAAAAAAAAAAFUJqiaTD5/PdnFJZqub/////////6beKXzoFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkEGl+dzPP/6XksDAAAAAAAAAAAAAABGjJTgavFzcyyhIrS////////////5serj0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABggiVXWMv/vsj0YlDAAAAAAAAAAAAAAMHTVejKWwwr+1x/n/////////////7t/Vp00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDCdFSlWU6fGrXy4eFgAAAAAAAAAAAAsZLlB5oLrQ3Of///////////////////7hnTkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwABGTAzP3bK78yGOiErIQUAAAAAAAAACRYsWIa63fH/////////////////////+d2/fCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAVMD1NdbXu6q9NGRoeGQ0AAAAAAAAJHTJbneH////////////////////////v0L+rcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwGCR4zP09ync3uwlwYBgkQHCQgEAULGig8VYfP///////////////////////////v5NewYRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAYMGSEkMFJ1pebdgSUAAAAIHTI9P0lieIyq3f//////////////////////////////9s2lVgEAAAAAAAAAAAAGBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgsRGBAROni19v+1RgAAAAAGIT9efqfM5///////////////////////////////////2a9yIQAAAAAAAAAAABUcDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwULGB0lEgQoecf0/995FAAAAAAJKV+az/3////////////////////////////////////coGowAAAAAAAAAAAAHD0pAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBA0hLzwhARxlq9n77JIkAAAAAAAVUJrV////////////////////+fT///nm+f//////+dKfaCkAAAAAAAAAAA0iRjwHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgEAAR5HZ0IUM3Wnz+/djS4AAAAAAAcwa6Xd///////////////////z4f7/39Lu///////76b9rDgAAAAAAAAAdPSkwMA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAkAAAAJ3uiZSlFg7DP4s+ENgcAAAAABhQvXJ3q//////////////////Pn//jQyM/X6v//+OfqqzcAAAAAAAAAABI6MDAzHgkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB4IAA1Gq7trNUZ5r8O/p2EoEAQFBwkRESFPlez/////////////////9Pb//9/Mt6qvx+bMpZRMAAAAAAAAAAAAABY1UmRJHgUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALDBglNV+tt3VMXJK7r5R7SSEQCw4RFiAkQoTP//////////////////////////HQqIyg2ch/MwAAAAAAAAAAAAAABihfnZRKFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhAFHTY/aJ+YZUZntcCRe21HKBoSEBQaJUaM3P//////////////////////+Pn76dS9p6/V2n4JAAAAAAAAAAAAAAQLKG3H1Yc5DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcJxElOkOPx5JKMGjCuIeGeUonHhwVEhUrddL////////////////////////4+em6r8/fzcqzWAAAAAAAAAAAAAAAFCRMkdDSom82DQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSkhES5MZb30t1k5eMfHsreXWTUhGRUSHU2o+P//////////////////////////77OkzdzFolgLAAAAAAAAAAAAAAASRXKdx8+7q3gyCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGgAAHEJ+zfTDbUl4x+Lf2qhlQigYFBo5gd3////////////////////////////2xaqdnJJSAgAAAAAHDgAABAAAAAVHdpjN6eLcu2spDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwEAAAMMo3d36BrXIrV6ubqvWo3JCAgL1+y/////////////////////////+/7//TVs3tlTQsAAAAAAA0SAAcoBQAAAC5llcjm7vnvqFwkBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZHAAAAAkvkdzDf1xnr/bz6f7ffz0kHSdFidn/////////////////////////+fjmwKqSakYNAAAAAAAHDQQAABQEAAAAGEl2pc3s///IeTAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACs1AAAAEU2q1bt8TFy1///5/+mkYjIeL16o7v//////////////////////////9qtrXFVPLwAAAAAAAAQGAAAAAAAAAAAMNV6RwOz//9mUQBUJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJLykBAAw2ku75z4dTZaj0///51bOHRSc9drv2///////++//////////////////5nEozQ0kVAAAAAAAAAAAAAAAAAAAAAA5Ccpe44v303a9YGgcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATk8DAAAGF7H///afkZcoPb///bMspRWLkaHwPH//////fH2//////////////////6/bzc3MgAAAAAAAAAAAAAAAAAAAAAAHluVs7q7yNfPt3MuDAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANjIAAAAQcN///8dbKUqt//////bcuoFJXqDP+f/////c7P///////////////////+azazIAAAAAAAAAAAAAAAAAAAAAAAY3eL3ZvZSfx8jCoFkhCwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOCwAAAByM+f//tVIuSrX////////4unh5sOr//////+T0/////////////////////+yyWAAAAAAAAAAAAAAAAAAAAAAAJG239P3DkaTDwNDQgSwOCwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOFAgAAAAAPbX///+1WSs/q//////////FhmqN5P///////////////////////////////9+EDAAAAAAAAAAAAAAAAAAABilkre7//+mvpLC62e6qRhYLBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEvGgYAAA5cx////8BYHD2z////////86VqSWjZ////////////////////////////////33wLAAAAAAAAAAAAAAAAAA09g7/n/////+GomLPQ58hqJQwCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQNTkiEQAAK5fs////6n4sUMX////////sklI6Z9r////////////////////////////////UWwAAAAAAAAAAAAAAAAUpWJXh////////9r+Xp7e1q20rDQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCckHUJrUiEVAgBNz///////rVJhwv////////ONPzBq3P///////////////////////////////81AAAAAAAAAAAAAAAAWRoHD+P////////npzaWPkZGRazISBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ4oPzc1Ypp2LxkFCXb5///////CeXan3P//////6oc2ImHZ////////////////////////////////0jYAAAAAAAAAAAAAFk2U1////////////vHisnlyhJR1OhkHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABonKT1JQEZojHtPLxUwq////////+e/p6Cy0vP////qj0MhVdD////////////////////////////////VNgAAAAAAAAAAABVJhtf////////////77tyvg3WGon88FggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQJCkyTFhHTG9+dnNWP2/d///////////it6Sgw/////+qTSdTvf///////////////////////////////7gpAAAAAAAAAAAHPYTF////////////89XIyrqqkpi1j0IVBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESkvKS4/Rz1GfpqGfHh1pfv////////////QlHaa5P///8hcN2rD///////////////////////////////UfBIAAAAAAAAAABllu+7////////////pxcrh2bqdp7OVVhwGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYgMjozKScvPGGlyKKBeITC//////////////61hInC////5oxomuf/////////////////////////////2nk8BAAAAAAAAAAAKXCrwtz//////////uzn8/TcsJylmoRTHQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFiszOjopIS9NkdnduKKJkeT///////////////vFp8r////+u4+1+f////////////////////////////+RPy8VAAAAAAAAAAAwW2pigdL///jm///v6f3/9uTNvauKb0AUBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkhLzMzOTowP3K44ce3w7rN///////////////////q/f/////KlLf/////////////////////////////vVZAXkUAAAAAAAAAACA2MydMr///9Ob///Hk8/356tzHnW9VMg4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEhwhLi4yQDZNmNDMr7ja5v7//////////////////////////9SfwP///////////////////////////9ptNVmVcwkAAAAAAAAADBESGkOk+///////+O7x+PHawK+SYUMpCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYcHiApLjM8L0Wc2tC7x+r/////////////////////////////5sDa////////////////////////////qzMhZbOdIgAAAAAAAAcOEBkoPZHz//////nc2urx8eHHuKdvPyACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFScrKCEoPUVGZ7js5Nzh+//////////////////////////////cw+T///////////////////b///////+gIhRbtbI6AAAAAAAQICgrOkVDe9z/////3MC6x9ns9unStYFHGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZKC4uIS5JT2Kl6vju5ub//////////////////////////////8iz4f/////////////////+7P///////5EcAi91diwAAAAADBooPU1ZX1Nwx////+fQ1biaq8/v++a/lFUWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABRkkKSwvQFBTarDk2tnHv+/////////////////////////////cu8jv////////7+z////////////////ngRkAByQiDAYNERQdKC85RVVcU2S4////7+LfrYOcv9Xv58CSTREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJHCgvLzM8P0xtorunp6Cf1///////////////////////////5Kqy5P//+/b7+/nfx+///////////////+qYKAAABwcCDhUWGSEwPDo/TU9JWar/////9M+il623wuHcvYxFDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsZLj01LiwsTYmvsJKGhIa/////////////////5+bz//////TIrcr5/+fF1///6cWy3P//////////////+btGAgACBQcSFhgcITJFRUlVT0ZZqv7////0yqiyt6i94te1fjYFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAkNTMuJyVQoMzQuqSJeK3////////////25LqNg5i/3NC4sr/X8//z0Lvi///cu8rq/v/////////////9z2QNAAUIDBIWGBocJzk9P1BSSVuk9v///+e9pKuklLXm3bBtJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIGDR0nJyQhJ0qNyunq2reSqvP//////////8+ddVxYebXNqIOY1fbx2sfM3////+/V3O/////////////////neRQABgcICw0OERQWJzA3SkxHVYPH////5rudkoNtj9XapFsWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgYVJygcGBooQ3W78f722rKw5P//////////uGhMXHCYzMeakr/k1K2Uj7Da/f///+/Q2v////////////////+KHQUGBQcHBwYMGB0pNT1NTE1VapTH8f/uyqKJdVZ1w8eDNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEECEvLCEgIig3a8L////kysDX8f////////uaR0BniaKrl4y44cWKb2t1oMjS5Pv/78DF////////////////8YQhCAcGDRAMBw4cHCU2P0ZPW15faHyo1Nq9mpSKZXawqmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkWJCUoLzU2LCxivf////bm0Mrm////////xWUuM1iRqJqJjauvf15hc4mour/a+f/nv8X////////////////hiSgFAgcYHRQQFRkSFik2MjpVXFlTUnOan4p7h41vcI+ESQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxAZHSUvNj0sKWHC////9vPqz+H//////+6JNR4rT5/IvbCceWJWW3CNmpKSuOr9///q9P///////////////+qoOgUCCxYVDA4WFhASISwrNUlQUFZea3NrYmuDh3JeZVglAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDRQdJyUiJyEpZM3////5///XyOr/////wGIsJzdfr+HawI1PP1l1jY97c4G77/v//////////////////////bdFDAwNDAgGCA4UEhQiLDA6QkdHWHNrUExWcoyBZUpALwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYSGSElIRgWITZyyP///////9e63P///9d/Qi4vQG2w19SiXzlDc5+leVt7qs/U2fT///////////////7////5lCsIDQwJBwYGDBkYFBkgLDpARlBkc1Y2OlZ8jGpHMyEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABhAVGBwdGRgnR4zU/v//////1cLs////rVUnHCdAb6rIx6d2ZXiqv5RcZaDMv4+UyPj///js/////+rIwvP//9pbDQQICQkEAAANIiQcGRglNTpFXHBhPCkwUHh5UzIaBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDA4SGBYUGSQ9eLPU/f///93F0Pn//8d1NxoWKDxeotXSuq2wsr2wg3CNq6qMZG+w5v//2bfS38zCr4N+ref/wkAFBAYLDAQAAAshJyEeHCIuMjlPW0wvICA8ZGVHJQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICxIeHR0lJCg9Xn+q2unHq7jQ5+m7bTUZFB0pMlOn5NnAzenXqIqXuruchHl2irjp//+6e3yDcG1wU0dVeauVMAAAAQkNBQAABRUeHBIWKDIzLCw1NSkeHDBVVjoUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIIFCIoLzcrISIwRVt/lIaHpbKwlGE3IRESHSIvW6jc4uz//+6rncXhu42Ej6vCyOH+0G81LjInJzUsJykvRkANAAAABwsCAAACDh0hGRknKyskGSElIBwYITk3HgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYZJzA8TEY3OTw3MDxDR1t1f2dDLB0VERggIjBZn9f4/////tDN18ir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';\n","import { useEffect, useRef, useState, type CSSProperties } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { PORTRAIT_TONE_B64, PORTRAIT_TONE_SIZE } from './portrait-tone';\n\n/*\n * The deck's halftone, screened live. The portrait's ink is a small tone grid;\n * this draws it as dots on a 45° screen that grow in from the centre, breathe,\n * and part under the pointer like a lens. One path fill per frame; it sleeps\n * when offscreen or hidden, and draws once, still, under reduced motion.\n */\n\nexport interface Tone {\n size: number;\n data: Uint8Array;\n}\n\nlet portrait: Tone | null = null;\n/** The deck portrait's ink, decoded once. */\nexport function portraitTone(): Tone {\n if (!portrait) {\n const bin = atob(PORTRAIT_TONE_B64);\n const data = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) data[i] = bin.charCodeAt(i);\n portrait = { size: PORTRAIT_TONE_SIZE, data };\n }\n return portrait;\n}\n\nexport interface HalftoneCanvasProps {\n /** Ink to screen; the deck portrait by default. */\n tone?: Tone;\n /** Dots across the diameter. */\n density?: number;\n /** Swell and part the dots under the pointer. */\n lens?: boolean;\n /** Grow the dots in from the centre on first view. */\n intro?: boolean;\n /** A slow wave through the dots. */\n breathe?: boolean;\n /** Dot colour. */\n ink?: string;\n /** Shown before the canvas runs, and without script. */\n fallbackSrc?: string;\n alt: string;\n className?: string;\n style?: CSSProperties;\n}\n\nfunction sample(tone: Tone, u: number, v: number): number {\n const n = tone.size;\n const x = Math.min(n - 1.001, Math.max(0, u * n - 0.5));\n const y = Math.min(n - 1.001, Math.max(0, v * n - 0.5));\n const x0 = Math.floor(x);\n const y0 = Math.floor(y);\n const fx = x - x0;\n const fy = y - y0;\n const d = tone.data;\n const a = d[y0 * n + x0]! * (1 - fx) + d[y0 * n + x0 + 1]! * fx;\n const b = d[(y0 + 1) * n + x0]! * (1 - fx) + d[(y0 + 1) * n + x0 + 1]! * fx;\n return (a * (1 - fy) + b * fy) / 255;\n}\n\nconst easeOut = (k: number) => 1 - Math.pow(1 - k, 3);\n\nexport function HalftoneCanvas({\n tone,\n density = 86,\n lens = true,\n intro = true,\n breathe = true,\n ink = '#0d0a08',\n fallbackSrc,\n alt,\n className,\n style,\n}: HalftoneCanvasProps) {\n const wrap = useRef<HTMLDivElement>(null);\n const canvas = useRef<HTMLCanvasElement>(null);\n const [live, setLive] = useState(false);\n\n useEffect(() => {\n const el = wrap.current;\n const cv = canvas.current;\n if (!el || !cv) return;\n const ctx = cv.getContext('2d');\n if (!ctx) return;\n const t = tone ?? portraitTone();\n const still = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n let size = 0;\n let dots = new Float32Array(0); // x, y, r, delay per dot\n let count = 0;\n const pointer = { x: 0, y: 0, tx: 0, ty: 0, k: 0, on: false };\n let start = 0;\n let raf = 0;\n let visible = true;\n\n function layout() {\n const s = el!.clientWidth;\n if (!s || s === size) return;\n size = s;\n const dpr = Math.min(2, window.devicePixelRatio || 1);\n cv!.width = Math.round(s * dpr);\n cv!.height = Math.round(s * dpr);\n ctx!.setTransform(dpr, 0, 0, dpr, 0, 0);\n const pitch = s / density;\n const c = s / 2;\n const ca = Math.SQRT1_2;\n const span = Math.ceil((s * 0.75) / pitch) + 1;\n const out: number[] = [];\n for (let i = -span; i <= span; i++) {\n for (let j = -span; j <= span; j++) {\n const u = i * pitch;\n const v = j * pitch;\n const x = c + (u - v) * ca;\n const y = c + (u + v) * ca;\n const dc = Math.hypot(x - c, y - c);\n if (dc > c - pitch * 0.6) continue;\n const inkv = sample(t, x / s, y / s);\n if (inkv < 0.1) continue;\n const r = pitch * Math.sqrt(inkv / Math.PI) * 1.1;\n out.push(x, y, r, (dc / c) * 1100);\n }\n }\n dots = Float32Array.from(out);\n count = out.length / 4;\n }\n\n function frame(now: number) {\n if (!start) start = now;\n const el2 = now - start;\n pointer.x += (pointer.tx - pointer.x) * 0.18;\n pointer.y += (pointer.ty - pointer.y) * 0.18;\n pointer.k += ((pointer.on ? 1 : 0) - pointer.k) * 0.12;\n const L = size * 0.22;\n ctx!.clearRect(0, 0, size, size);\n ctx!.fillStyle = ink;\n ctx!.beginPath();\n const wave = breathe && !still;\n const sec = now / 1000;\n for (let n = 0; n < count; n++) {\n let x = dots[n * 4]!;\n let y = dots[n * 4 + 1]!;\n let r = dots[n * 4 + 2]!;\n if (intro && !still) {\n const k = Math.min(1, Math.max(0, (el2 - dots[n * 4 + 3]!) / 650));\n if (k <= 0) continue;\n r *= easeOut(k);\n }\n if (wave) r *= 1 + 0.05 * Math.sin(sec * 1.1 + ((x + y) / size) * 6);\n if (pointer.k > 0.01) {\n const dx = x - pointer.x;\n const dy = y - pointer.y;\n const d = Math.hypot(dx, dy);\n if (d < L) {\n // A clearing, like a finger drawn through sand: dots\n // shrink toward the pointer and part around it.\n const f = (1 - d / L) * pointer.k;\n r *= 1 - 0.75 * f * f;\n if (d > 0.001) {\n const push = f * (size / density) * 2.6;\n x += (dx / d) * push;\n y += (dy / d) * push;\n }\n }\n }\n ctx!.moveTo(x + r, y);\n ctx!.arc(x, y, r, 0, Math.PI * 2);\n }\n ctx!.fill();\n const introDone = !intro || still || el2 > 1900;\n const busy = wave || pointer.k > 0.01 || !introDone;\n raf = busy && visible && !document.hidden ? requestAnimationFrame(frame) : 0;\n }\n\n const kick = () => {\n if (!raf && visible && !document.hidden) raf = requestAnimationFrame(frame);\n };\n\n layout();\n setLive(true);\n kick();\n\n const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(() => (layout(), kick())) : null;\n ro?.observe(el);\n const io =\n typeof IntersectionObserver !== 'undefined'\n ? new IntersectionObserver(([e]) => {\n visible = Boolean(e?.isIntersecting);\n kick();\n })\n : null;\n io?.observe(el);\n const onVis = () => kick();\n document.addEventListener('visibilitychange', onVis);\n\n const move = (e: PointerEvent) => {\n const b = el.getBoundingClientRect();\n pointer.tx = e.clientX - b.left;\n pointer.ty = e.clientY - b.top;\n if (!pointer.on) {\n pointer.x = pointer.tx;\n pointer.y = pointer.ty;\n }\n pointer.on = true;\n kick();\n };\n const leave = () => {\n pointer.on = false;\n kick();\n };\n if (lens && !still) {\n el.addEventListener('pointermove', move);\n el.addEventListener('pointerleave', leave);\n }\n return () => {\n cancelAnimationFrame(raf);\n ro?.disconnect();\n io?.disconnect();\n document.removeEventListener('visibilitychange', onVis);\n el.removeEventListener('pointermove', move);\n el.removeEventListener('pointerleave', leave);\n };\n }, [tone, density, lens, intro, breathe, ink]);\n\n return (\n <div ref={wrap} className={cn('relative aspect-square w-full', className)} style={style} data-live={live || undefined}>\n {fallbackSrc ? (\n // eslint-disable-next-line @next/next/no-img-element -- the still screen, until the live one draws\n <img\n src={fallbackSrc}\n alt=\"\"\n aria-hidden\n className={cn('absolute inset-0 size-full select-none transition-opacity duration-300', live && 'opacity-0')}\n draggable={false}\n />\n ) : null}\n <canvas ref={canvas} role=\"img\" aria-label={alt} className=\"absolute inset-0 size-full\" />\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { HalftoneCanvas } from './halftone-canvas';\n\n/*\n * The deck's photograph: a halftone portrait on an orange ball, lit from the\n * upper left, with a hairline stadium behind it. The dot layer is an image of\n * black dots on transparent, made by scripts/halftone.py, so the ball stays CSS\n * and the dots stay crisp at any size.\n */\n\nexport const SPHERE_GRADIENT =\n 'radial-gradient(86% 86% at 36% 32%, #fff7f0 0%, #ffdec8 14%, #ffa069 34%, #ff7030 56%, #f65210 78%, #de4006 100%)';\n\nconst SPHERE_DEPTH = 'inset -14px -22px 44px rgb(150 40 0 / 0.16), 0 36px 70px -34px rgb(234 88 11 / 0.45)';\n\nexport interface HalftoneSphereProps {\n /** The dot layer (black dots on transparent, already circular). */\n src: string;\n /** Describe the person or subject; empty string marks it decorative. */\n alt: string;\n /** Draw the hairline stadium behind the sphere, as the hero does. */\n stadium?: boolean;\n /** Let the sphere drift a few pixels. Off under reduced motion. */\n float?: boolean;\n /** Screen the portrait live (draw-in, breathing, pointer lens); `src` stays the still fallback. */\n live?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n// A soft light on the upper left and a floor shadow, so the ball reads as an object.\nconst SPHERE_GLOSS = 'radial-gradient(38% 30% at 33% 22%, rgb(255 255 255 / 0.55), transparent 72%)';\n\nfunction Ball({ src, alt, float, live }: { src: string; alt: string; float: boolean; live: boolean }) {\n return (\n <div className={cn('relative size-full', float && 'oca-animate-float')}>\n <div\n aria-hidden\n className=\"absolute inset-x-[14%] -bottom-[7%] h-[10%] rounded-[50%] bg-[rgb(234_88_11/0.28)] blur-2xl\"\n />\n <div\n className=\"relative size-full overflow-hidden rounded-full\"\n style={{ background: SPHERE_GRADIENT, boxShadow: SPHERE_DEPTH }}\n >\n {live ? (\n <HalftoneCanvas fallbackSrc={src} alt={alt} />\n ) : (\n // eslint-disable-next-line @next/next/no-img-element -- a static dot layer, sized by CSS\n <img src={src} alt={alt} className=\"absolute inset-0 size-full select-none\" draggable={false} />\n )}\n <div\n aria-hidden\n className=\"pointer-events-none absolute inset-0 rounded-full mix-blend-soft-light\"\n style={{ background: SPHERE_GLOSS }}\n />\n </div>\n </div>\n );\n}\n\nexport function HalftoneSphere({\n src,\n alt,\n stadium = false,\n float = false,\n live = false,\n className,\n style,\n}: HalftoneSphereProps) {\n if (!stadium) {\n return (\n <div className={cn('relative aspect-square w-full', className)} style={style}>\n <Ball src={src} alt={alt} float={float} live={live} />\n </div>\n );\n }\n // Measured from the deck's title slide against the ball's width S: the stadium\n // starts 0.255 S left of and 0.127 S above the ball, is 1.11 S wide, and ends\n // level with its foot. Both live inside this box, so nothing reaches the text.\n return (\n <div className={cn('relative aspect-[1.255/1.127] w-full', className)} style={style}>\n <div aria-hidden className=\"oca-stadium pointer-events-none absolute left-0 top-0 h-full w-[88.4%] rounded-[32%]\" />\n <div className=\"absolute bottom-0 right-0 aspect-square w-[79.7%]\">\n <Ball src={src} alt={alt} float={float} live={live} />\n </div>\n </div>\n );\n}\n","import { useEffect, useRef } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Mark } from './mark';\n\nexport interface IsoCheckProps {\n /** Width in px; the check keeps its 2:1 grid. */\n size?: number;\n /** Drop it into place on first paint, the deck's closing gesture. */\n settle?: boolean;\n /** A soft floor shadow, so it reads as an object on the canvas. */\n shadow?: boolean;\n /** Turn a few degrees toward the pointer, with a warm light behind it. */\n tilt?: boolean;\n title?: string;\n className?: string;\n}\n\n/** The isometric check as an object: the deck's closing illustration. */\nexport function IsoCheck({ size = 360, settle = false, shadow = true, tilt = false, title, className }: IsoCheckProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el || !tilt || window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;\n let raf = 0;\n let tx = 0;\n let ty = 0;\n let x = 0;\n let y = 0;\n const step = () => {\n x += (tx - x) * 0.08;\n y += (ty - y) * 0.08;\n el.style.setProperty('--rx', `${(-y * 10).toFixed(2)}deg`);\n el.style.setProperty('--ry', `${(x * 14).toFixed(2)}deg`);\n raf = Math.abs(tx - x) + Math.abs(ty - y) > 0.001 ? requestAnimationFrame(step) : 0;\n };\n const move = (e: PointerEvent) => {\n const b = el.getBoundingClientRect();\n tx = Math.max(-1, Math.min(1, (e.clientX - (b.left + b.width / 2)) / (window.innerWidth / 2)));\n ty = Math.max(-1, Math.min(1, (e.clientY - (b.top + b.height / 2)) / (window.innerHeight / 2)));\n if (!raf) raf = requestAnimationFrame(step);\n };\n window.addEventListener('pointermove', move, { passive: true });\n return () => {\n cancelAnimationFrame(raf);\n window.removeEventListener('pointermove', move);\n };\n }, [tilt]);\n\n return (\n <div\n ref={ref}\n className={cn('relative inline-block', settle && 'oca-animate-settle', className)}\n style={{ width: size, perspective: tilt ? 900 : undefined }}\n >\n {tilt ? (\n <div\n aria-hidden\n className=\"absolute left-1/2 top-1/2 -z-0 aspect-square w-[120%] -translate-x-1/2 -translate-y-1/2 rounded-full opacity-70 blur-3xl\"\n style={{ background: 'radial-gradient(closest-side, rgb(255 140 70 / 0.35), transparent)' }}\n />\n ) : null}\n <div\n className=\"relative z-10 transition-transform duration-300 ease-out\"\n style={tilt ? { transform: 'rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg))', transformStyle: 'preserve-3d' } : undefined}\n >\n <Mark size={size} title={title} className=\"block\" />\n </div>\n {shadow ? (\n <div\n aria-hidden\n className=\"absolute left-[8%] right-[8%] rounded-[50%] opacity-60 blur-xl\"\n style={{ height: size * 0.08, bottom: -size * 0.04, background: 'rgb(234 88 11 / 0.18)' }}\n />\n ) : null}\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/*\n * \"A bot farm can pretend to be a crowd\": a crowd of identical figures in\n * perspective, nearer rows larger, with a few real ones in orange. Identical on\n * purpose: copies are what a bot farm is. Positions come from a fixed seed so\n * server and client draw the same crowd.\n */\n\nexport interface CrowdProps {\n cols?: number;\n rows?: number;\n /** How many figures are real (orange). */\n real?: number;\n seed?: number;\n /** Ground it sits on: figures are light on ink, dark on canvas. */\n tone?: 'ink' | 'canvas';\n /** Spoken by screen readers. */\n label?: string;\n /**\n * Let the copies leave as an ancestor's `--p` (0 to 1, set by ScrollStory)\n * rises: each fake falls away at its own moment and the real ones grow.\n */\n story?: boolean;\n className?: string;\n}\n\nconst CELL_W = 22;\nconst CELL_H = 27;\n\nfunction picks(count: number, total: number, seed: number): Set<number> {\n let s = seed >>> 0;\n const out = new Set<number>();\n while (out.size < Math.min(count, total)) {\n s = (Math.imul(s, 1664525) + 1013904223) >>> 0;\n out.add(s % total);\n }\n return out;\n}\n\nexport function Crowd({\n cols = 26,\n rows = 9,\n real = 7,\n seed = 21,\n tone = 'ink',\n label = 'A crowd of identical accounts. Only a few are real.',\n story = false,\n className,\n}: CrowdProps) {\n const width = cols * CELL_W;\n const scales = Array.from({ length: rows }, (_, r) => 0.5 + 0.5 * (r / Math.max(1, rows - 1)));\n const height = scales.reduce((h, s) => h + CELL_H * s, 0);\n // Real figures only in the nearer half, where they are big enough to see.\n const nearFrom = Math.floor(rows / 2) * cols;\n const realSet = new Set([...picks(real, rows * cols - nearFrom, seed)].map((i) => i + nearFrom));\n const bot = tone === 'ink' ? '#ffffff' : '#0a0a0a';\n // When each copy leaves, from a fixed seed: nearer rows go a little later.\n let lcg = (seed * 7919) >>> 0;\n const leaveAt = () => {\n lcg = (Math.imul(lcg, 1664525) + 1013904223) >>> 0;\n return 0.12 + (lcg / 2 ** 32) * 0.6;\n };\n let y = 0;\n return (\n <svg\n role=\"img\"\n aria-label={label}\n viewBox={`0 0 ${width} ${Math.ceil(height)}`}\n className={cn('block h-auto w-full overflow-visible', className)}\n >\n {story ? (\n <defs>\n <radialGradient id=\"oca-crowd-glow\">\n <stop offset=\"0\" stopColor=\"#ff7a3d\" stopOpacity=\"0.55\" />\n <stop offset=\"1\" stopColor=\"#ff7a3d\" stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n ) : null}\n {scales.map((s, r) => {\n const rowY = y;\n y += CELL_H * s;\n const rowW = cols * CELL_W * s;\n const x0 = (width - rowW) / 2;\n return Array.from({ length: cols }, (_, c) => {\n const i = r * cols + c;\n const isReal = realSet.has(i);\n const t = leaveAt();\n return (\n <g key={i} transform={`translate(${x0 + c * CELL_W * s} ${rowY}) scale(${s})`}>\n {isReal && story ? (\n <circle className=\"oca-crowd-halo\" cx={11} cy={14} r={13} fill=\"url(#oca-crowd-glow)\" />\n ) : null}\n <g\n className={story ? (isReal ? 'oca-crowd-real' : 'oca-crowd-bot') : undefined}\n style={story && !isReal ? ({ '--t': t.toFixed(3) } as CSSProperties) : undefined}\n fill={isReal ? 'var(--oca-orange)' : bot}\n fillOpacity={isReal ? 1 : 0.1 + 0.16 * s}\n >\n <circle cx={11} cy={8} r={4.4} />\n <path d=\"M3 25a8 8.5 0 0 1 16 0Z\" />\n </g>\n </g>\n );\n });\n })}\n </svg>\n );\n}\n"]}
|
package/dist/components.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ReactNode, HTMLAttributes } from 'react';
|
|
2
|
+
import { ReactNode, HTMLAttributes, ElementType, CSSProperties } from 'react';
|
|
3
3
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
@@ -535,4 +535,45 @@ declare function ActivityList({ items, empty, className }: {
|
|
|
535
535
|
className?: string;
|
|
536
536
|
}): react.JSX.Element;
|
|
537
537
|
|
|
538
|
-
|
|
538
|
+
declare function useInView<T extends Element>(rootMargin?: string): readonly [react.RefObject<T | null>, boolean];
|
|
539
|
+
declare function Reveal({ as, delay, className, style, children, }: {
|
|
540
|
+
as?: ElementType;
|
|
541
|
+
delay?: number;
|
|
542
|
+
className?: string;
|
|
543
|
+
style?: CSSProperties;
|
|
544
|
+
children: ReactNode;
|
|
545
|
+
}): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
|
|
546
|
+
declare function ScrollStory({ length, className, innerClassName, children, }: {
|
|
547
|
+
length?: number;
|
|
548
|
+
className?: string;
|
|
549
|
+
innerClassName?: string;
|
|
550
|
+
children: ReactNode;
|
|
551
|
+
}): react.JSX.Element;
|
|
552
|
+
declare function Ticker({ value, duration, format, className, }: {
|
|
553
|
+
value: number;
|
|
554
|
+
duration?: number;
|
|
555
|
+
format?: (n: number) => string;
|
|
556
|
+
className?: string;
|
|
557
|
+
}): react.JSX.Element;
|
|
558
|
+
|
|
559
|
+
declare function PhoneFrame({ className, style, children }: {
|
|
560
|
+
className?: string;
|
|
561
|
+
style?: CSSProperties;
|
|
562
|
+
children: ReactNode;
|
|
563
|
+
}): react.JSX.Element;
|
|
564
|
+
declare function BrowserFrame({ url, className, style, children, }: {
|
|
565
|
+
url?: string;
|
|
566
|
+
className?: string;
|
|
567
|
+
style?: CSSProperties;
|
|
568
|
+
children: ReactNode;
|
|
569
|
+
}): react.JSX.Element;
|
|
570
|
+
declare function FloatChip({ icon, title, detail, delay, className, style, }: {
|
|
571
|
+
icon?: ReactNode;
|
|
572
|
+
title: ReactNode;
|
|
573
|
+
detail?: ReactNode;
|
|
574
|
+
delay?: number;
|
|
575
|
+
className?: string;
|
|
576
|
+
style?: CSSProperties;
|
|
577
|
+
}): react.JSX.Element;
|
|
578
|
+
|
|
579
|
+
export { Accent, type ActivityItem, ActivityList, BrowserFrame, CodeBlock, type Column, Container, CopyButton, DataTable, Display, type DisplayProps, DocHeader, DocLayout, EmptyLine, EmptyState, Eyebrow, FloatChip, Footnote, HashChip, type KeyValueItem, KeyValueList, Lead, LoadingBlock, Notice, PackageCard, type PackageItem, PageHeader, PageHero, type PageHeroProps, PhoneFrame, type ProgressStep, ProgressSteps, Prose, Reveal, Sats, SatsFigure, type SatsProps, type SatsTextOptions, ScrollStory, Section, SectionIntro, type SectionProps, SplitBar, type SplitSegment, StatCard, type StatCardProps, StatGrid, type StatGridProps, StepGrid, type StepGridProps, type StepItem, type StepState, Ticker, type TocItem, type TruthRow, type TruthStatus, TruthTable, UsdApprox, satsText, sectionVariants, useCopy, useInView };
|
package/dist/components.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ReactNode, HTMLAttributes } from 'react';
|
|
2
|
+
import { ReactNode, HTMLAttributes, ElementType, CSSProperties } from 'react';
|
|
3
3
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
@@ -535,4 +535,45 @@ declare function ActivityList({ items, empty, className }: {
|
|
|
535
535
|
className?: string;
|
|
536
536
|
}): react.JSX.Element;
|
|
537
537
|
|
|
538
|
-
|
|
538
|
+
declare function useInView<T extends Element>(rootMargin?: string): readonly [react.RefObject<T | null>, boolean];
|
|
539
|
+
declare function Reveal({ as, delay, className, style, children, }: {
|
|
540
|
+
as?: ElementType;
|
|
541
|
+
delay?: number;
|
|
542
|
+
className?: string;
|
|
543
|
+
style?: CSSProperties;
|
|
544
|
+
children: ReactNode;
|
|
545
|
+
}): react.ReactElement<any, string | react.JSXElementConstructor<any>>;
|
|
546
|
+
declare function ScrollStory({ length, className, innerClassName, children, }: {
|
|
547
|
+
length?: number;
|
|
548
|
+
className?: string;
|
|
549
|
+
innerClassName?: string;
|
|
550
|
+
children: ReactNode;
|
|
551
|
+
}): react.JSX.Element;
|
|
552
|
+
declare function Ticker({ value, duration, format, className, }: {
|
|
553
|
+
value: number;
|
|
554
|
+
duration?: number;
|
|
555
|
+
format?: (n: number) => string;
|
|
556
|
+
className?: string;
|
|
557
|
+
}): react.JSX.Element;
|
|
558
|
+
|
|
559
|
+
declare function PhoneFrame({ className, style, children }: {
|
|
560
|
+
className?: string;
|
|
561
|
+
style?: CSSProperties;
|
|
562
|
+
children: ReactNode;
|
|
563
|
+
}): react.JSX.Element;
|
|
564
|
+
declare function BrowserFrame({ url, className, style, children, }: {
|
|
565
|
+
url?: string;
|
|
566
|
+
className?: string;
|
|
567
|
+
style?: CSSProperties;
|
|
568
|
+
children: ReactNode;
|
|
569
|
+
}): react.JSX.Element;
|
|
570
|
+
declare function FloatChip({ icon, title, detail, delay, className, style, }: {
|
|
571
|
+
icon?: ReactNode;
|
|
572
|
+
title: ReactNode;
|
|
573
|
+
detail?: ReactNode;
|
|
574
|
+
delay?: number;
|
|
575
|
+
className?: string;
|
|
576
|
+
style?: CSSProperties;
|
|
577
|
+
}): react.JSX.Element;
|
|
578
|
+
|
|
579
|
+
export { Accent, type ActivityItem, ActivityList, BrowserFrame, CodeBlock, type Column, Container, CopyButton, DataTable, Display, type DisplayProps, DocHeader, DocLayout, EmptyLine, EmptyState, Eyebrow, FloatChip, Footnote, HashChip, type KeyValueItem, KeyValueList, Lead, LoadingBlock, Notice, PackageCard, type PackageItem, PageHeader, PageHero, type PageHeroProps, PhoneFrame, type ProgressStep, ProgressSteps, Prose, Reveal, Sats, SatsFigure, type SatsProps, type SatsTextOptions, ScrollStory, Section, SectionIntro, type SectionProps, SplitBar, type SplitSegment, StatCard, type StatCardProps, StatGrid, type StatGridProps, StepGrid, type StepGridProps, type StepItem, type StepState, Ticker, type TocItem, type TruthRow, type TruthStatus, TruthTable, UsdApprox, satsText, sectionVariants, useCopy, useInView };
|
package/dist/components.js
CHANGED
|
@@ -1118,9 +1118,209 @@ function SatsFigure({
|
|
|
1118
1118
|
hint ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] text-muted-foreground", children: hint }) : null
|
|
1119
1119
|
] });
|
|
1120
1120
|
}
|
|
1121
|
+
function prefersStill() {
|
|
1122
|
+
return typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1123
|
+
}
|
|
1124
|
+
function useInView(rootMargin = "0px 0px -12% 0px") {
|
|
1125
|
+
const ref = react.useRef(null);
|
|
1126
|
+
const [seen, setSeen] = react.useState(false);
|
|
1127
|
+
react.useEffect(() => {
|
|
1128
|
+
const el = ref.current;
|
|
1129
|
+
if (!el || seen) return;
|
|
1130
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
1131
|
+
setSeen(true);
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
const io = new IntersectionObserver(
|
|
1135
|
+
([e]) => {
|
|
1136
|
+
if (e?.isIntersecting) {
|
|
1137
|
+
setSeen(true);
|
|
1138
|
+
io.disconnect();
|
|
1139
|
+
}
|
|
1140
|
+
},
|
|
1141
|
+
{ rootMargin }
|
|
1142
|
+
);
|
|
1143
|
+
io.observe(el);
|
|
1144
|
+
return () => io.disconnect();
|
|
1145
|
+
}, [rootMargin, seen]);
|
|
1146
|
+
return [ref, seen];
|
|
1147
|
+
}
|
|
1148
|
+
function Reveal({
|
|
1149
|
+
as = "div",
|
|
1150
|
+
delay = 0,
|
|
1151
|
+
className,
|
|
1152
|
+
style,
|
|
1153
|
+
children
|
|
1154
|
+
}) {
|
|
1155
|
+
const ref = react.useRef(null);
|
|
1156
|
+
react.useEffect(() => {
|
|
1157
|
+
const el = ref.current;
|
|
1158
|
+
if (!el || prefersStill() || typeof IntersectionObserver === "undefined") return;
|
|
1159
|
+
if (el.getBoundingClientRect().top < window.innerHeight * 0.92) return;
|
|
1160
|
+
el.dataset.reveal = "pending";
|
|
1161
|
+
const io = new IntersectionObserver(
|
|
1162
|
+
([e]) => {
|
|
1163
|
+
if (e?.isIntersecting) {
|
|
1164
|
+
el.dataset.reveal = "shown";
|
|
1165
|
+
io.disconnect();
|
|
1166
|
+
}
|
|
1167
|
+
},
|
|
1168
|
+
{ rootMargin: "0px 0px -10% 0px" }
|
|
1169
|
+
);
|
|
1170
|
+
io.observe(el);
|
|
1171
|
+
return () => io.disconnect();
|
|
1172
|
+
}, []);
|
|
1173
|
+
return react.createElement(
|
|
1174
|
+
as,
|
|
1175
|
+
{ ref, className, style: { ...style, "--reveal-delay": `${delay}ms` } },
|
|
1176
|
+
children
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
function ScrollStory({
|
|
1180
|
+
length = 2,
|
|
1181
|
+
className,
|
|
1182
|
+
innerClassName,
|
|
1183
|
+
children
|
|
1184
|
+
}) {
|
|
1185
|
+
const ref = react.useRef(null);
|
|
1186
|
+
const [pinned, setPinned] = react.useState(false);
|
|
1187
|
+
react.useEffect(() => {
|
|
1188
|
+
const el = ref.current;
|
|
1189
|
+
if (!el || prefersStill()) return;
|
|
1190
|
+
setPinned(true);
|
|
1191
|
+
let raf = 0;
|
|
1192
|
+
const update = () => {
|
|
1193
|
+
raf = 0;
|
|
1194
|
+
const r = el.getBoundingClientRect();
|
|
1195
|
+
const travel = r.height - window.innerHeight;
|
|
1196
|
+
const p = travel > 0 ? Math.min(1, Math.max(0, -r.top / travel)) : 0;
|
|
1197
|
+
el.style.setProperty("--p", p.toFixed(4));
|
|
1198
|
+
};
|
|
1199
|
+
const on = () => {
|
|
1200
|
+
if (!raf) raf = requestAnimationFrame(update);
|
|
1201
|
+
};
|
|
1202
|
+
update();
|
|
1203
|
+
window.addEventListener("scroll", on, { passive: true });
|
|
1204
|
+
window.addEventListener("resize", on);
|
|
1205
|
+
return () => {
|
|
1206
|
+
cancelAnimationFrame(raf);
|
|
1207
|
+
window.removeEventListener("scroll", on);
|
|
1208
|
+
window.removeEventListener("resize", on);
|
|
1209
|
+
};
|
|
1210
|
+
}, []);
|
|
1211
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("relative", className), style: pinned ? { height: `${length * 100}svh` } : void 0, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(pinned && "sticky top-0 flex min-h-svh items-center", innerClassName), children }) });
|
|
1212
|
+
}
|
|
1213
|
+
function Ticker({
|
|
1214
|
+
value,
|
|
1215
|
+
duration = 1200,
|
|
1216
|
+
format = (n) => Math.round(n).toLocaleString("en-US"),
|
|
1217
|
+
className
|
|
1218
|
+
}) {
|
|
1219
|
+
const [ref, seen] = useInView();
|
|
1220
|
+
const [shown, setShown] = react.useState(value);
|
|
1221
|
+
const animate = react.useRef(null);
|
|
1222
|
+
react.useEffect(() => {
|
|
1223
|
+
const el = ref.current;
|
|
1224
|
+
if (!el || animate.current !== null) return;
|
|
1225
|
+
animate.current = !prefersStill() && el.getBoundingClientRect().top > window.innerHeight * 0.9;
|
|
1226
|
+
if (animate.current) setShown(0);
|
|
1227
|
+
}, [ref]);
|
|
1228
|
+
react.useEffect(() => {
|
|
1229
|
+
if (!seen) return;
|
|
1230
|
+
if (!animate.current) {
|
|
1231
|
+
setShown(value);
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
let raf = 0;
|
|
1235
|
+
const t0 = performance.now();
|
|
1236
|
+
const step = (now) => {
|
|
1237
|
+
const k = Math.min(1, (now - t0) / duration);
|
|
1238
|
+
setShown(value * (1 - Math.pow(1 - k, 3)));
|
|
1239
|
+
if (k < 1) raf = requestAnimationFrame(step);
|
|
1240
|
+
};
|
|
1241
|
+
raf = requestAnimationFrame(step);
|
|
1242
|
+
return () => cancelAnimationFrame(raf);
|
|
1243
|
+
}, [seen, value, duration]);
|
|
1244
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: cn("oca-tabular", className), children: format(shown) });
|
|
1245
|
+
}
|
|
1246
|
+
function PhoneFrame({ className, style, children }) {
|
|
1247
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1248
|
+
"div",
|
|
1249
|
+
{
|
|
1250
|
+
className: cn(
|
|
1251
|
+
"relative w-[17.5rem] shrink-0 rounded-[2.9rem] bg-[#0b0b0c] p-[0.6rem]",
|
|
1252
|
+
"shadow-[0_50px_100px_-40px_rgb(10_10_10/0.55),0_0_0_1px_rgb(255_255_255/0.06)_inset]",
|
|
1253
|
+
className
|
|
1254
|
+
),
|
|
1255
|
+
style,
|
|
1256
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative aspect-[9/19.2] overflow-hidden rounded-[2.35rem] bg-background", children: [
|
|
1257
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, className: "absolute left-1/2 top-2.5 z-10 h-[1.35rem] w-[5.6rem] -translate-x-1/2 rounded-full bg-[#0b0b0c]" }),
|
|
1258
|
+
children
|
|
1259
|
+
] })
|
|
1260
|
+
}
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
function BrowserFrame({
|
|
1264
|
+
url = "ochk.app",
|
|
1265
|
+
className,
|
|
1266
|
+
style,
|
|
1267
|
+
children
|
|
1268
|
+
}) {
|
|
1269
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1270
|
+
"div",
|
|
1271
|
+
{
|
|
1272
|
+
className: cn(
|
|
1273
|
+
"overflow-hidden rounded-[1.1rem] border border-border bg-card",
|
|
1274
|
+
"shadow-[0_40px_90px_-40px_rgb(10_10_10/0.45)]",
|
|
1275
|
+
className
|
|
1276
|
+
),
|
|
1277
|
+
style,
|
|
1278
|
+
children: [
|
|
1279
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-10 items-center gap-3 border-b border-border px-4", children: [
|
|
1280
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-hidden": true, className: "flex gap-1.5", children: [
|
|
1281
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2.5 rounded-full bg-[#ff5f57]" }),
|
|
1282
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2.5 rounded-full bg-[#febc2e]" }),
|
|
1283
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2.5 rounded-full bg-[#28c840]" })
|
|
1284
|
+
] }),
|
|
1285
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto flex h-6 min-w-0 max-w-[60%] flex-1 items-center justify-center rounded-md bg-muted px-3 text-[0.75rem] text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: url }) }),
|
|
1286
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "w-[2.6rem]" })
|
|
1287
|
+
] }),
|
|
1288
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children })
|
|
1289
|
+
]
|
|
1290
|
+
}
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1293
|
+
function FloatChip({
|
|
1294
|
+
icon,
|
|
1295
|
+
title,
|
|
1296
|
+
detail,
|
|
1297
|
+
delay = 0,
|
|
1298
|
+
className,
|
|
1299
|
+
style
|
|
1300
|
+
}) {
|
|
1301
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1302
|
+
"div",
|
|
1303
|
+
{
|
|
1304
|
+
className: cn(
|
|
1305
|
+
"oca-animate-drift flex items-center gap-3 rounded-2xl border border-border bg-card/90 py-2.5 pl-2.5 pr-4 backdrop-blur-md",
|
|
1306
|
+
"shadow-[0_24px_50px_-24px_rgb(10_10_10/0.35)]",
|
|
1307
|
+
className
|
|
1308
|
+
),
|
|
1309
|
+
style: { animationDelay: `${-delay}s`, ...style },
|
|
1310
|
+
children: [
|
|
1311
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-xl bg-muted text-foreground [&_svg]:size-4", children: icon }) : null,
|
|
1312
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
|
|
1313
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] font-medium leading-tight", children: title }),
|
|
1314
|
+
detail ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.8125rem] leading-tight text-muted-foreground", children: detail }) : null
|
|
1315
|
+
] })
|
|
1316
|
+
]
|
|
1317
|
+
}
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1121
1320
|
|
|
1122
1321
|
exports.Accent = Accent;
|
|
1123
1322
|
exports.ActivityList = ActivityList;
|
|
1323
|
+
exports.BrowserFrame = BrowserFrame;
|
|
1124
1324
|
exports.CodeBlock = CodeBlock;
|
|
1125
1325
|
exports.Container = Container;
|
|
1126
1326
|
exports.CopyButton = CopyButton;
|
|
@@ -1131,6 +1331,7 @@ exports.DocLayout = DocLayout;
|
|
|
1131
1331
|
exports.EmptyLine = EmptyLine;
|
|
1132
1332
|
exports.EmptyState = EmptyState;
|
|
1133
1333
|
exports.Eyebrow = Eyebrow;
|
|
1334
|
+
exports.FloatChip = FloatChip;
|
|
1134
1335
|
exports.Footnote = Footnote;
|
|
1135
1336
|
exports.HashChip = HashChip;
|
|
1136
1337
|
exports.KeyValueList = KeyValueList;
|
|
@@ -1140,20 +1341,25 @@ exports.Notice = Notice;
|
|
|
1140
1341
|
exports.PackageCard = PackageCard;
|
|
1141
1342
|
exports.PageHeader = PageHeader;
|
|
1142
1343
|
exports.PageHero = PageHero;
|
|
1344
|
+
exports.PhoneFrame = PhoneFrame;
|
|
1143
1345
|
exports.ProgressSteps = ProgressSteps;
|
|
1144
1346
|
exports.Prose = Prose;
|
|
1347
|
+
exports.Reveal = Reveal;
|
|
1145
1348
|
exports.Sats = Sats;
|
|
1146
1349
|
exports.SatsFigure = SatsFigure;
|
|
1350
|
+
exports.ScrollStory = ScrollStory;
|
|
1147
1351
|
exports.Section = Section;
|
|
1148
1352
|
exports.SectionIntro = SectionIntro;
|
|
1149
1353
|
exports.SplitBar = SplitBar;
|
|
1150
1354
|
exports.StatCard = StatCard;
|
|
1151
1355
|
exports.StatGrid = StatGrid;
|
|
1152
1356
|
exports.StepGrid = StepGrid;
|
|
1357
|
+
exports.Ticker = Ticker;
|
|
1153
1358
|
exports.TruthTable = TruthTable;
|
|
1154
1359
|
exports.UsdApprox = UsdApprox;
|
|
1155
1360
|
exports.satsText = satsText;
|
|
1156
1361
|
exports.sectionVariants = sectionVariants;
|
|
1157
1362
|
exports.useCopy = useCopy;
|
|
1363
|
+
exports.useInView = useInView;
|
|
1158
1364
|
//# sourceMappingURL=components.js.map
|
|
1159
1365
|
//# sourceMappingURL=components.js.map
|