@orangecheck/app-design 0.6.0 → 1.0.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/README.md +4 -3
- package/dist/brand.js.map +1 -1
- package/dist/brand.mjs.map +1 -1
- package/dist/chrome.d.mts +49 -15
- package/dist/chrome.d.ts +49 -15
- package/dist/chrome.js +619 -55
- package/dist/chrome.js.map +1 -1
- package/dist/chrome.mjs +617 -57
- package/dist/chrome.mjs.map +1 -1
- package/dist/components.d.mts +231 -1
- package/dist/components.d.ts +231 -1
- package/dist/components.js +1187 -2
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +1162 -5
- package/dist/components.mjs.map +1 -1
- package/dist/family.d.mts +2 -0
- package/dist/family.d.ts +2 -0
- package/dist/family.js +167 -0
- package/dist/family.js.map +1 -0
- package/dist/family.mjs +154 -0
- package/dist/family.mjs.map +1 -0
- package/dist/index-C6hDqOOS.d.mts +58 -0
- package/dist/index-C6hDqOOS.d.ts +58 -0
- package/dist/index.d.mts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +1619 -132
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1575 -134
- package/dist/index.mjs.map +1 -1
- package/dist/primitives.d.mts +52 -1
- package/dist/primitives.d.ts +52 -1
- package/dist/primitives.js +280 -3
- package/dist/primitives.js.map +1 -1
- package/dist/primitives.mjs +271 -6
- package/dist/primitives.mjs.map +1 -1
- package/dist/status-badge-BEOxeY9j.d.ts +13 -0
- package/dist/status-badge-DRwGhB0h.d.mts +13 -0
- package/dist/styles/fonts.css +1 -1
- package/dist/styles/tokens.css +4 -2
- package/dist/tokens.d.mts +3 -1
- package/dist/tokens.d.ts +3 -1
- package/dist/tokens.js +5 -3
- package/dist/tokens.js.map +1 -1
- package/dist/tokens.mjs +5 -3
- package/dist/tokens.mjs.map +1 -1
- package/package.json +9 -2
package/dist/components.js
CHANGED
|
@@ -9,6 +9,14 @@ var lucideReact = require('lucide-react');
|
|
|
9
9
|
var reactSlot = require('@radix-ui/react-slot');
|
|
10
10
|
var SeparatorPrimitive = require('@radix-ui/react-separator');
|
|
11
11
|
require('sonner');
|
|
12
|
+
var Link = require('next/link');
|
|
13
|
+
var CheckboxPrimitive = require('@radix-ui/react-checkbox');
|
|
14
|
+
var LabelPrimitive = require('@radix-ui/react-label');
|
|
15
|
+
var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
16
|
+
var SelectPrimitive = require('@radix-ui/react-select');
|
|
17
|
+
var SwitchPrimitive = require('@radix-ui/react-switch');
|
|
18
|
+
|
|
19
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
20
|
|
|
13
21
|
function _interopNamespace(e) {
|
|
14
22
|
if (e && e.__esModule) return e;
|
|
@@ -29,6 +37,12 @@ function _interopNamespace(e) {
|
|
|
29
37
|
}
|
|
30
38
|
|
|
31
39
|
var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
|
|
40
|
+
var Link__default = /*#__PURE__*/_interopDefault(Link);
|
|
41
|
+
var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
|
|
42
|
+
var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
|
|
43
|
+
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
44
|
+
var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
|
|
45
|
+
var SwitchPrimitive__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitive);
|
|
32
46
|
|
|
33
47
|
var merge = tailwindMerge.extendTailwindMerge({
|
|
34
48
|
extend: {
|
|
@@ -365,13 +379,13 @@ var badgeVariants = classVarianceAuthority.cva(
|
|
|
365
379
|
tone: {
|
|
366
380
|
neutral: "border-border bg-card text-foreground",
|
|
367
381
|
muted: "border-transparent bg-muted text-muted-foreground",
|
|
368
|
-
brand: "border-transparent bg-[color-mix(in_oklab,var(--oca-orange)
|
|
382
|
+
brand: "border-transparent bg-[color-mix(in_oklab,var(--oca-orange)_9%,var(--card))] text-oca-accent-ink",
|
|
369
383
|
danger: "border-transparent bg-[color-mix(in_oklab,var(--destructive)_12%,var(--card))] text-destructive",
|
|
370
384
|
// A good state is a neutral pill with a green dot, not a green pill.
|
|
371
385
|
success: GOOD_DOT,
|
|
372
386
|
// Aliases kept so older call sites keep compiling: attention is
|
|
373
387
|
// the brand accent, information is neutral.
|
|
374
|
-
warning: "border-transparent bg-[color-mix(in_oklab,var(--oca-orange)
|
|
388
|
+
warning: "border-transparent bg-[color-mix(in_oklab,var(--oca-orange)_9%,var(--card))] text-oca-accent-ink",
|
|
375
389
|
info: "border-border bg-card text-foreground",
|
|
376
390
|
// Inverted in dark mode, where ink would sit on a card of nearly its own colour.
|
|
377
391
|
ink: "border-transparent bg-oca-ink text-oca-ink-foreground dark:bg-foreground dark:text-background",
|
|
@@ -1455,11 +1469,1166 @@ var ErrorBoundary = class extends react.Component {
|
|
|
1455
1469
|
) });
|
|
1456
1470
|
}
|
|
1457
1471
|
};
|
|
1472
|
+
var TOP = "0,3 2,2 6,4 14,0 16,1 6,6";
|
|
1473
|
+
var LEFT = "0,3 6,6 6,8 0,5";
|
|
1474
|
+
var RIGHT = "6,6 16,1 16,3 6,8";
|
|
1475
|
+
var MARK_FACES = { top: "#FED8AB", left: "#FB933C", right: "#EA580B" };
|
|
1476
|
+
function Mark({ title, size, className, ...rest }) {
|
|
1477
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1478
|
+
"svg",
|
|
1479
|
+
{
|
|
1480
|
+
viewBox: "0 0 16 8",
|
|
1481
|
+
width: size,
|
|
1482
|
+
height: size ? size / 2 : void 0,
|
|
1483
|
+
role: title ? "img" : void 0,
|
|
1484
|
+
"aria-hidden": title ? void 0 : true,
|
|
1485
|
+
className: cn("shrink-0", className),
|
|
1486
|
+
...rest,
|
|
1487
|
+
children: [
|
|
1488
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: title }) : null,
|
|
1489
|
+
/* @__PURE__ */ jsxRuntime.jsx("polygon", { points: LEFT, fill: MARK_FACES.left }),
|
|
1490
|
+
/* @__PURE__ */ jsxRuntime.jsx("polygon", { points: RIGHT, fill: MARK_FACES.right }),
|
|
1491
|
+
/* @__PURE__ */ jsxRuntime.jsx("polygon", { points: TOP, fill: MARK_FACES.top })
|
|
1492
|
+
]
|
|
1493
|
+
}
|
|
1494
|
+
);
|
|
1495
|
+
}
|
|
1496
|
+
function MarkOutline({ className }) {
|
|
1497
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "-0.2 -0.2 16.4 8.4", "aria-hidden": true, className: cn("shrink-0 overflow-visible", className), children: [TOP, LEFT, RIGHT].map((points) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1498
|
+
"polygon",
|
|
1499
|
+
{
|
|
1500
|
+
points,
|
|
1501
|
+
fill: "none",
|
|
1502
|
+
stroke: "currentColor",
|
|
1503
|
+
strokeWidth: "1",
|
|
1504
|
+
strokeLinejoin: "round",
|
|
1505
|
+
vectorEffect: "non-scaling-stroke"
|
|
1506
|
+
},
|
|
1507
|
+
points
|
|
1508
|
+
)) });
|
|
1509
|
+
}
|
|
1510
|
+
var WORDS = {
|
|
1511
|
+
404: {
|
|
1512
|
+
name: "Not found",
|
|
1513
|
+
title: "This page isn\u2019t here.",
|
|
1514
|
+
detail: "The link may be old, or the address mistyped."
|
|
1515
|
+
},
|
|
1516
|
+
500: {
|
|
1517
|
+
name: "Server error",
|
|
1518
|
+
title: "Something broke on our side.",
|
|
1519
|
+
detail: "Try again in a moment."
|
|
1520
|
+
}
|
|
1521
|
+
};
|
|
1522
|
+
function ErrorPage({
|
|
1523
|
+
code = 404,
|
|
1524
|
+
title,
|
|
1525
|
+
detail,
|
|
1526
|
+
actions,
|
|
1527
|
+
home = "/",
|
|
1528
|
+
art,
|
|
1529
|
+
className
|
|
1530
|
+
}) {
|
|
1531
|
+
const words = WORDS[code] ?? (code >= 500 ? WORDS[500] : WORDS[404]);
|
|
1532
|
+
const server = code >= 500;
|
|
1533
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Section, { space: "none", className: cn("flex min-h-[min(40rem,72dvh)] items-center py-16 md:py-24", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 items-center gap-12 md:grid-cols-12", children: [
|
|
1534
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-w-[40rem] flex-col items-start gap-6 md:col-span-7", children: [
|
|
1535
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "oca-eyebrow oca-enter", children: [
|
|
1536
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular", children: code }),
|
|
1537
|
+
" \xB7 ",
|
|
1538
|
+
WORDS[code]?.name ?? (server ? "Error" : "Not available")
|
|
1539
|
+
] }),
|
|
1540
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "oca-display-2 oca-enter [--enter-delay:70ms]", children: title ?? words.title }),
|
|
1541
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-lead oca-enter [--enter-delay:150ms]", children: detail ?? words.detail }),
|
|
1542
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-enter flex flex-wrap gap-3 [--enter-delay:230ms]", children: actions ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1543
|
+
server ? /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => window.location.reload(), children: "Try again" }) : null,
|
|
1544
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, variant: server ? "secondary" : "primary", children: /* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href: home, children: "Go home" }) })
|
|
1545
|
+
] }) })
|
|
1546
|
+
] }),
|
|
1547
|
+
art !== null ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, className: "oca-enter hidden justify-center md:col-span-5 md:flex [--enter-delay:120ms]", children: art ?? /* @__PURE__ */ jsxRuntime.jsx(MarkOutline, { className: "w-full max-w-[20rem] text-oca-hairline-strong" }) }) : null
|
|
1548
|
+
] }) });
|
|
1549
|
+
}
|
|
1550
|
+
function IsoCheck({ size = 360, settle = false, shadow = true, tilt = false, title, className }) {
|
|
1551
|
+
const ref = react.useRef(null);
|
|
1552
|
+
react.useEffect(() => {
|
|
1553
|
+
const el = ref.current;
|
|
1554
|
+
if (!el || !tilt || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
1555
|
+
let raf = 0;
|
|
1556
|
+
let tx = 0;
|
|
1557
|
+
let ty = 0;
|
|
1558
|
+
let x = 0;
|
|
1559
|
+
let y = 0;
|
|
1560
|
+
const step = () => {
|
|
1561
|
+
x += (tx - x) * 0.08;
|
|
1562
|
+
y += (ty - y) * 0.08;
|
|
1563
|
+
el.style.setProperty("--rx", `${(-y * 10).toFixed(2)}deg`);
|
|
1564
|
+
el.style.setProperty("--ry", `${(x * 14).toFixed(2)}deg`);
|
|
1565
|
+
raf = Math.abs(tx - x) + Math.abs(ty - y) > 1e-3 ? requestAnimationFrame(step) : 0;
|
|
1566
|
+
};
|
|
1567
|
+
const move = (e) => {
|
|
1568
|
+
const b = el.getBoundingClientRect();
|
|
1569
|
+
tx = Math.max(-1, Math.min(1, (e.clientX - (b.left + b.width / 2)) / (window.innerWidth / 2)));
|
|
1570
|
+
ty = Math.max(-1, Math.min(1, (e.clientY - (b.top + b.height / 2)) / (window.innerHeight / 2)));
|
|
1571
|
+
if (!raf) raf = requestAnimationFrame(step);
|
|
1572
|
+
};
|
|
1573
|
+
window.addEventListener("pointermove", move, { passive: true });
|
|
1574
|
+
return () => {
|
|
1575
|
+
cancelAnimationFrame(raf);
|
|
1576
|
+
window.removeEventListener("pointermove", move);
|
|
1577
|
+
};
|
|
1578
|
+
}, [tilt]);
|
|
1579
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1580
|
+
"div",
|
|
1581
|
+
{
|
|
1582
|
+
ref,
|
|
1583
|
+
className: cn("relative inline-block", settle && "oca-animate-settle", className),
|
|
1584
|
+
style: { width: size, perspective: tilt ? 900 : void 0 },
|
|
1585
|
+
children: [
|
|
1586
|
+
tilt ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1587
|
+
"div",
|
|
1588
|
+
{
|
|
1589
|
+
"aria-hidden": true,
|
|
1590
|
+
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",
|
|
1591
|
+
style: { background: "radial-gradient(closest-side, rgb(255 140 70 / 0.35), transparent)" }
|
|
1592
|
+
}
|
|
1593
|
+
) : null,
|
|
1594
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1595
|
+
"div",
|
|
1596
|
+
{
|
|
1597
|
+
className: "relative z-10 transition-transform duration-300 ease-out",
|
|
1598
|
+
style: tilt ? { transform: "rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg))", transformStyle: "preserve-3d" } : void 0,
|
|
1599
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Mark, { size, title, className: "block" })
|
|
1600
|
+
}
|
|
1601
|
+
),
|
|
1602
|
+
shadow ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1603
|
+
"div",
|
|
1604
|
+
{
|
|
1605
|
+
"aria-hidden": true,
|
|
1606
|
+
className: "absolute left-[8%] right-[8%] rounded-[50%] opacity-60 blur-xl",
|
|
1607
|
+
style: { height: size * 0.08, bottom: -size * 0.04, background: "rgb(234 88 11 / 0.18)" }
|
|
1608
|
+
}
|
|
1609
|
+
) : null
|
|
1610
|
+
]
|
|
1611
|
+
}
|
|
1612
|
+
);
|
|
1613
|
+
}
|
|
1614
|
+
var GroupName = react.createContext(void 0);
|
|
1615
|
+
function Accordion({
|
|
1616
|
+
single = false,
|
|
1617
|
+
children,
|
|
1618
|
+
className
|
|
1619
|
+
}) {
|
|
1620
|
+
const name = react.useId();
|
|
1621
|
+
return /* @__PURE__ */ jsxRuntime.jsx(GroupName.Provider, { value: single ? name : void 0, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("divide-y divide-border overflow-hidden rounded-[1.25rem] border border-border bg-card", className), children }) });
|
|
1622
|
+
}
|
|
1623
|
+
function AccordionItem({
|
|
1624
|
+
title,
|
|
1625
|
+
children,
|
|
1626
|
+
defaultOpen = false,
|
|
1627
|
+
id,
|
|
1628
|
+
className
|
|
1629
|
+
}) {
|
|
1630
|
+
const name = react.useContext(GroupName);
|
|
1631
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("details", { id, name, open: defaultOpen || void 0, className: cn("group scroll-mt-24", className), children: [
|
|
1632
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1633
|
+
"summary",
|
|
1634
|
+
{
|
|
1635
|
+
className: cn(
|
|
1636
|
+
"flex min-h-14 cursor-pointer list-none items-center justify-between gap-4 px-5 py-4 text-[1rem] font-medium leading-snug md:px-6",
|
|
1637
|
+
// Inside the card's clip, so the ring is drawn within the row.
|
|
1638
|
+
"transition-colors hover:bg-accent/60 focus-visible:outline-offset-[-2px] [&::-webkit-details-marker]:hidden"
|
|
1639
|
+
),
|
|
1640
|
+
children: [
|
|
1641
|
+
title,
|
|
1642
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1643
|
+
lucideReact.ChevronDown,
|
|
1644
|
+
{
|
|
1645
|
+
"aria-hidden": true,
|
|
1646
|
+
className: "size-4 shrink-0 text-muted-foreground transition-transform duration-200 group-open:rotate-180"
|
|
1647
|
+
}
|
|
1648
|
+
)
|
|
1649
|
+
]
|
|
1650
|
+
}
|
|
1651
|
+
),
|
|
1652
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-body px-5 pb-5 text-[0.9375rem] md:px-6 md:pb-6", children })
|
|
1653
|
+
] });
|
|
1654
|
+
}
|
|
1655
|
+
function SectionHeading({
|
|
1656
|
+
eyebrow,
|
|
1657
|
+
title,
|
|
1658
|
+
lead,
|
|
1659
|
+
id,
|
|
1660
|
+
onInk = false,
|
|
1661
|
+
level = 2,
|
|
1662
|
+
as = "h2",
|
|
1663
|
+
align = "start",
|
|
1664
|
+
reveal = true,
|
|
1665
|
+
className
|
|
1666
|
+
}) {
|
|
1667
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(SectionIntro, { align, reveal, className: cn("max-w-3xl gap-4 md:gap-4", className), children: [
|
|
1668
|
+
eyebrow ? /* @__PURE__ */ jsxRuntime.jsx(Eyebrow, { onInk, children: eyebrow }) : null,
|
|
1669
|
+
/* @__PURE__ */ jsxRuntime.jsx(Display, { level, as, id, className: "scroll-mt-24", children: title }),
|
|
1670
|
+
lead ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("oca-lead", onInk && "text-oca-ink-muted"), children: lead }) : null
|
|
1671
|
+
] });
|
|
1672
|
+
}
|
|
1673
|
+
function FactBlock({
|
|
1674
|
+
id,
|
|
1675
|
+
title,
|
|
1676
|
+
description,
|
|
1677
|
+
aside,
|
|
1678
|
+
children,
|
|
1679
|
+
className
|
|
1680
|
+
}) {
|
|
1681
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("section", { id, className: cn("flex scroll-mt-24 flex-col gap-6", className), children: [
|
|
1682
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-end md:justify-between md:gap-8", children: [
|
|
1683
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-w-[44rem] flex-col gap-3", children: [
|
|
1684
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "oca-display-3", children: title }),
|
|
1685
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-body text-[1.0625rem]", children: description }) : null
|
|
1686
|
+
] }),
|
|
1687
|
+
aside ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 flex-wrap gap-x-5 gap-y-2 text-[0.9375rem]", children: aside }) : null
|
|
1688
|
+
] }),
|
|
1689
|
+
children
|
|
1690
|
+
] });
|
|
1691
|
+
}
|
|
1692
|
+
function FactRows({
|
|
1693
|
+
rows,
|
|
1694
|
+
columns = 1,
|
|
1695
|
+
label,
|
|
1696
|
+
className
|
|
1697
|
+
}) {
|
|
1698
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": label, className: cn("divide-y divide-border rounded-[1.25rem] border border-border bg-card", className), children: rows.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex flex-col gap-5 px-5 py-6 md:px-8 md:py-7", children: [
|
|
1699
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-x-6", children: [
|
|
1700
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-title min-w-0 text-pretty", children: r.title }),
|
|
1701
|
+
r.figure ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular shrink-0 whitespace-nowrap text-[1.75rem] leading-none tracking-[-0.02em]", children: r.figure }) : null
|
|
1702
|
+
] }),
|
|
1703
|
+
/* @__PURE__ */ jsxRuntime.jsx("dl", { className: columns === 2 ? "grid grid-cols-1 gap-x-10 gap-y-4 md:grid-cols-2" : "flex flex-col gap-4", children: r.fields.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
1704
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-[0.875rem] font-medium text-muted-foreground", children: f.label }),
|
|
1705
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { className: "break-words text-[1rem] leading-relaxed", children: f.value })
|
|
1706
|
+
] }, i)) })
|
|
1707
|
+
] }, r.key)) });
|
|
1708
|
+
}
|
|
1709
|
+
function EndpointList({ items, label, className }) {
|
|
1710
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": label, className: cn("divide-y divide-border rounded-[1.25rem] border border-border bg-card", className), children: items.map((a) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1711
|
+
"a",
|
|
1712
|
+
{
|
|
1713
|
+
href: a.href,
|
|
1714
|
+
target: "_blank",
|
|
1715
|
+
rel: "noreferrer",
|
|
1716
|
+
className: "flex flex-col gap-1 px-5 py-3.5 transition-colors hover:bg-accent/60 sm:flex-row sm:items-baseline sm:justify-between sm:gap-6",
|
|
1717
|
+
children: [
|
|
1718
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "break-all text-[0.875rem] text-foreground", children: a.label ?? a.href }),
|
|
1719
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[0.875rem] text-muted-foreground sm:text-right", children: [
|
|
1720
|
+
a.description,
|
|
1721
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " (opens in a new tab)" })
|
|
1722
|
+
] })
|
|
1723
|
+
]
|
|
1724
|
+
}
|
|
1725
|
+
) }, a.href)) });
|
|
1726
|
+
}
|
|
1727
|
+
function ProofStrip({ items, className }) {
|
|
1728
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("border-y border-border", className), children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "oca-container grid grid-cols-2 gap-x-6 gap-y-4 py-6 md:grid-cols-4", children: items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1729
|
+
"li",
|
|
1730
|
+
{
|
|
1731
|
+
className: "flex items-center gap-3 text-[0.9375rem] [&_svg]:size-[1.1rem] [&_svg]:shrink-0 [&_svg]:text-oca-accent-ink",
|
|
1732
|
+
children: [
|
|
1733
|
+
it.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "flex", children: it.icon }) : null,
|
|
1734
|
+
it.label
|
|
1735
|
+
]
|
|
1736
|
+
},
|
|
1737
|
+
i
|
|
1738
|
+
)) }) });
|
|
1739
|
+
}
|
|
1740
|
+
function Closing({
|
|
1741
|
+
title,
|
|
1742
|
+
lead,
|
|
1743
|
+
actions,
|
|
1744
|
+
art,
|
|
1745
|
+
className
|
|
1746
|
+
}) {
|
|
1747
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Section, { className: cn("overflow-hidden", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 items-center gap-12 md:grid-cols-12", children: [
|
|
1748
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Reveal, { className: "flex flex-col items-start gap-8 md:col-span-7", children: [
|
|
1749
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
|
|
1750
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "oca-display-1 text-[clamp(2.5rem,1.5rem+4vw,5rem)] leading-[1]", children: title }),
|
|
1751
|
+
lead ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-lead max-w-[34rem]", children: lead }) : null
|
|
1752
|
+
] }),
|
|
1753
|
+
actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-3", children: actions }) : null
|
|
1754
|
+
] }),
|
|
1755
|
+
art !== null ? (
|
|
1756
|
+
// Room under the check on a phone, so its glow fades before the band ends.
|
|
1757
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, className: "flex justify-center max-md:pb-16 md:col-span-5", children: art ?? /* @__PURE__ */ jsxRuntime.jsx(IsoCheck, { size: 340, settle: true, tilt: true, className: "max-w-full" }) })
|
|
1758
|
+
) : null
|
|
1759
|
+
] }) });
|
|
1760
|
+
}
|
|
1761
|
+
function Faq({
|
|
1762
|
+
items,
|
|
1763
|
+
className
|
|
1764
|
+
}) {
|
|
1765
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Accordion, { single: true, className, children: items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsx(AccordionItem, { id: it.id, title: it.q, children: it.a }, it.id ?? i)) });
|
|
1766
|
+
}
|
|
1767
|
+
var LINK = "text-foreground underline decoration-foreground/35 underline-offset-4 transition-colors hover:decoration-foreground";
|
|
1768
|
+
function TextLink({
|
|
1769
|
+
href,
|
|
1770
|
+
children,
|
|
1771
|
+
external,
|
|
1772
|
+
className
|
|
1773
|
+
}) {
|
|
1774
|
+
const internal = href.startsWith("/") && !href.startsWith("/api/") && !href.startsWith("/.well-known/");
|
|
1775
|
+
const offsite = external ?? /^https?:\/\//.test(href);
|
|
1776
|
+
if (internal && !offsite) {
|
|
1777
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href, className: cn(LINK, className), children });
|
|
1778
|
+
}
|
|
1779
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("a", { href, className: cn(LINK, className), ...offsite ? { target: "_blank", rel: "noreferrer" } : {}, children: [
|
|
1780
|
+
children,
|
|
1781
|
+
offsite ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: " (opens in a new tab)" }) : null
|
|
1782
|
+
] });
|
|
1783
|
+
}
|
|
1784
|
+
var PROPER = {
|
|
1785
|
+
kyc: "KYC",
|
|
1786
|
+
pii: "PII",
|
|
1787
|
+
ccpa: "CCPA",
|
|
1788
|
+
cpra: "CPRA",
|
|
1789
|
+
gdpr: "GDPR",
|
|
1790
|
+
uk: "UK",
|
|
1791
|
+
eu: "EU",
|
|
1792
|
+
california: "California",
|
|
1793
|
+
europe: "Europe",
|
|
1794
|
+
united: "United",
|
|
1795
|
+
kingdom: "Kingdom"
|
|
1796
|
+
};
|
|
1797
|
+
function headingCase(text) {
|
|
1798
|
+
const words = text.replace(/\b[a-z]+\b/g, (w) => PROPER[w] ?? w);
|
|
1799
|
+
if (/^orangecheck\b/.test(words)) return `OrangeCheck${words.slice("orangecheck".length)}`;
|
|
1800
|
+
return words.length === 0 ? words : words[0].toUpperCase() + words.slice(1);
|
|
1801
|
+
}
|
|
1802
|
+
function sentencesCase(text) {
|
|
1803
|
+
return text.split(/(?<=[.!?])\s+/).map((s) => headingCase(s)).join(" ");
|
|
1804
|
+
}
|
|
1805
|
+
function openSentence(text) {
|
|
1806
|
+
const first = /^\S+/.exec(text)?.[0] ?? "";
|
|
1807
|
+
if (!/^[a-z][a-z'’-]*,?$/.test(first)) return text;
|
|
1808
|
+
return text[0].toUpperCase() + text.slice(1);
|
|
1809
|
+
}
|
|
1810
|
+
var INLINE = /(\*\*[^*]+\*\*|`[^`]+`|\[[^\]]+\]\([^)]+\))/g;
|
|
1811
|
+
var LINK2 = /^\[([^\]]+)\]\(([^)]+)\)$/;
|
|
1812
|
+
function Inline({ text }) {
|
|
1813
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: text.split(INLINE).map((part, i) => {
|
|
1814
|
+
if (!part) return null;
|
|
1815
|
+
if (part.startsWith("**") && part.endsWith("**") && part.length > 4) {
|
|
1816
|
+
return /* @__PURE__ */ jsxRuntime.jsx("strong", { children: /* @__PURE__ */ jsxRuntime.jsx(Inline, { text: part.slice(2, -2) }) }, i);
|
|
1817
|
+
}
|
|
1818
|
+
if (part.startsWith("`") && part.endsWith("`") && part.length > 2) return /* @__PURE__ */ jsxRuntime.jsx("code", { children: part.slice(1, -1) }, i);
|
|
1819
|
+
const link = LINK2.exec(part);
|
|
1820
|
+
if (link) {
|
|
1821
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TextLink, { href: link[2] ?? "", children: link[1] }, i);
|
|
1822
|
+
}
|
|
1823
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: part }, i);
|
|
1824
|
+
}) });
|
|
1825
|
+
}
|
|
1826
|
+
function BlockView({ block }) {
|
|
1827
|
+
switch (block.kind) {
|
|
1828
|
+
case "para":
|
|
1829
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: block.text.split(/\n{2,}/).map((para, i) => /* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsx(Inline, { text: para }) }, i)) });
|
|
1830
|
+
case "subhead":
|
|
1831
|
+
return /* @__PURE__ */ jsxRuntime.jsx("h3", { children: /* @__PURE__ */ jsxRuntime.jsx(Inline, { text: headingCase(block.text) }) });
|
|
1832
|
+
case "bullets":
|
|
1833
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { children: block.items.map(
|
|
1834
|
+
(item, i) => typeof item === "string" ? /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(Inline, { text: item }) }, i) : /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
1835
|
+
/* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
|
|
1836
|
+
headingCase(item.k),
|
|
1837
|
+
"."
|
|
1838
|
+
] }),
|
|
1839
|
+
" ",
|
|
1840
|
+
/* @__PURE__ */ jsxRuntime.jsx(Inline, { text: openSentence(item.v) })
|
|
1841
|
+
] }, i)
|
|
1842
|
+
) });
|
|
1843
|
+
case "callout":
|
|
1844
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "not-prose my-6", children: /* @__PURE__ */ jsxRuntime.jsx(Notice, { tone: block.emphatic ? "brand" : "neutral", children: /* @__PURE__ */ jsxRuntime.jsx(Inline, { text: block.text }) }) });
|
|
1845
|
+
case "stub":
|
|
1846
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "not-prose my-6", children: /* @__PURE__ */ jsxRuntime.jsx(Notice, { tone: "brand", title: "Pending counsel review", children: /* @__PURE__ */ jsxRuntime.jsx(Inline, { text: block.text }) }) });
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
function LegalDocument({ doc, className }) {
|
|
1850
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1851
|
+
DocLayout,
|
|
1852
|
+
{
|
|
1853
|
+
className,
|
|
1854
|
+
header: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1855
|
+
DocHeader,
|
|
1856
|
+
{
|
|
1857
|
+
eyebrow: headingCase(doc.eyebrow),
|
|
1858
|
+
title: doc.title,
|
|
1859
|
+
lead: doc.description,
|
|
1860
|
+
meta: `Effective ${doc.effective} \xB7 last updated ${doc.updated}`
|
|
1861
|
+
}
|
|
1862
|
+
),
|
|
1863
|
+
toc: doc.sections.map((s) => ({ id: s.id, label: headingCase(s.heading) })),
|
|
1864
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("article", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs(Prose, { children: [
|
|
1865
|
+
doc.preamble?.map((b, i) => /* @__PURE__ */ jsxRuntime.jsx(BlockView, { block: b }, i)),
|
|
1866
|
+
doc.sections.map((s) => /* @__PURE__ */ jsxRuntime.jsxs("section", { children: [
|
|
1867
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { id: s.id, className: "scroll-mt-24", children: [
|
|
1868
|
+
s.num ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "oca-tabular text-muted-foreground", children: [
|
|
1869
|
+
s.num,
|
|
1870
|
+
" "
|
|
1871
|
+
] }) : null,
|
|
1872
|
+
headingCase(s.heading)
|
|
1873
|
+
] }),
|
|
1874
|
+
s.hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.9375rem]", children: headingCase(s.hint) }) : null,
|
|
1875
|
+
s.blocks.map((b, i) => /* @__PURE__ */ jsxRuntime.jsx(BlockView, { block: b }, i))
|
|
1876
|
+
] }, s.id)),
|
|
1877
|
+
doc.summary ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-14 border-t border-border pt-6 text-[0.9375rem]", children: [
|
|
1878
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "In short." }),
|
|
1879
|
+
" ",
|
|
1880
|
+
sentencesCase(doc.summary.replace(/^summary:\s*/i, ""))
|
|
1881
|
+
] }) : null
|
|
1882
|
+
] }) })
|
|
1883
|
+
}
|
|
1884
|
+
);
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
// src/family/index.ts
|
|
1888
|
+
var OCHK_IO = "https://ochk.io";
|
|
1889
|
+
var DOCS_HREF = `${OCHK_IO}/docs`;
|
|
1890
|
+
function protocol(slug, verb, line, kinds) {
|
|
1891
|
+
return {
|
|
1892
|
+
slug,
|
|
1893
|
+
label: slug,
|
|
1894
|
+
href: `${OCHK_IO}/${slug}`,
|
|
1895
|
+
group: "protocol",
|
|
1896
|
+
line,
|
|
1897
|
+
status: "live",
|
|
1898
|
+
verb,
|
|
1899
|
+
pageHref: `${OCHK_IO}/${slug}`,
|
|
1900
|
+
toolHref: `https://${slug}.ochk.io`,
|
|
1901
|
+
specHref: `https://github.com/orangecheck/oc-${slug}-protocol`,
|
|
1902
|
+
kinds
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
var PROTOCOLS = [
|
|
1906
|
+
protocol("attest", "identity", "Show that an address holds bitcoin, and for how long.", "30078"),
|
|
1907
|
+
protocol("lock", "confidentiality", "Encrypt to a Bitcoin address, so only its holder can open it.", "30078"),
|
|
1908
|
+
protocol("vote", "legitimacy", "Polls weighed in sats, that anyone can tally.", "30080\u201330082"),
|
|
1909
|
+
protocol("stamp", "provenance", "Prove who signed something, and when.", "30083"),
|
|
1910
|
+
protocol("agent", "authority", "Give software scoped, revocable permission to act for you.", "30083\u201330086"),
|
|
1911
|
+
protocol("pledge", "commitment", "Make a promise with bitcoin behind it, on a public record.", "30078")
|
|
1912
|
+
];
|
|
1913
|
+
var PROTOCOL_ORDER = PROTOCOLS.map((p) => p.slug);
|
|
1914
|
+
var FAMILY = [
|
|
1915
|
+
{
|
|
1916
|
+
slug: "home",
|
|
1917
|
+
label: "ochk.io",
|
|
1918
|
+
href: OCHK_IO,
|
|
1919
|
+
group: "orangecheck",
|
|
1920
|
+
line: "The open protocols, and the company behind them.",
|
|
1921
|
+
status: "live"
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
slug: "me",
|
|
1925
|
+
label: "ochk.app",
|
|
1926
|
+
href: "https://ochk.app",
|
|
1927
|
+
group: "orangecheck",
|
|
1928
|
+
line: "One account, with Bitcoin behind it.",
|
|
1929
|
+
status: "testing"
|
|
1930
|
+
},
|
|
1931
|
+
{
|
|
1932
|
+
slug: "docs",
|
|
1933
|
+
label: "docs",
|
|
1934
|
+
href: DOCS_HREF,
|
|
1935
|
+
group: "orangecheck",
|
|
1936
|
+
line: "Specs, SDKs and guides for every protocol.",
|
|
1937
|
+
status: "live"
|
|
1938
|
+
},
|
|
1939
|
+
...PROTOCOLS,
|
|
1940
|
+
{
|
|
1941
|
+
slug: "vault",
|
|
1942
|
+
label: "vault",
|
|
1943
|
+
href: "https://vault.ochk.io",
|
|
1944
|
+
group: "app",
|
|
1945
|
+
line: "A password manager, encrypted in your browser.",
|
|
1946
|
+
status: "live",
|
|
1947
|
+
protocols: ["lock"]
|
|
1948
|
+
},
|
|
1949
|
+
{
|
|
1950
|
+
slug: "chat",
|
|
1951
|
+
label: "chat",
|
|
1952
|
+
href: "https://chat.ochk.io",
|
|
1953
|
+
group: "app",
|
|
1954
|
+
line: "Messages only the holder of a Bitcoin address can read.",
|
|
1955
|
+
status: "testing",
|
|
1956
|
+
protocols: ["lock"]
|
|
1957
|
+
},
|
|
1958
|
+
{
|
|
1959
|
+
slug: "cosign",
|
|
1960
|
+
label: "cosign",
|
|
1961
|
+
href: "https://cosign.ochk.io",
|
|
1962
|
+
group: "app",
|
|
1963
|
+
line: "Builders find co-founders and backers.",
|
|
1964
|
+
status: "testing",
|
|
1965
|
+
protocols: ["attest"]
|
|
1966
|
+
},
|
|
1967
|
+
{
|
|
1968
|
+
slug: "me-demo",
|
|
1969
|
+
// "demo", not the made-up app's own name, so nobody takes it for ours.
|
|
1970
|
+
label: "demo",
|
|
1971
|
+
href: "https://me-demo.ochk.io",
|
|
1972
|
+
group: "app",
|
|
1973
|
+
line: "Lumen Notes, a made-up app that signs in with orangecheck.",
|
|
1974
|
+
status: "live"
|
|
1975
|
+
},
|
|
1976
|
+
{
|
|
1977
|
+
slug: "globe",
|
|
1978
|
+
label: "globe",
|
|
1979
|
+
href: "https://globe.ochk.io",
|
|
1980
|
+
group: "public-good",
|
|
1981
|
+
line: "The Bitcoin network, live, on a globe.",
|
|
1982
|
+
status: "live"
|
|
1983
|
+
},
|
|
1984
|
+
{
|
|
1985
|
+
slug: "btc",
|
|
1986
|
+
label: "btc",
|
|
1987
|
+
href: "https://btc.ochk.io",
|
|
1988
|
+
group: "public-good",
|
|
1989
|
+
line: "A free desk for reading the Bitcoin market.",
|
|
1990
|
+
status: "live"
|
|
1991
|
+
}
|
|
1992
|
+
];
|
|
1993
|
+
var BY_SLUG = new Map(FAMILY.map((s) => [s.slug, s]));
|
|
1994
|
+
function protocolSite(slug) {
|
|
1995
|
+
return BY_SLUG.get(slug);
|
|
1996
|
+
}
|
|
1997
|
+
[
|
|
1998
|
+
{
|
|
1999
|
+
href: `${OCHK_IO}/protocols`,
|
|
2000
|
+
label: "Protocols",
|
|
2001
|
+
children: PROTOCOLS.map((p) => ({ href: p.pageHref, label: p.label, description: p.line }))
|
|
2002
|
+
},
|
|
2003
|
+
{ href: `${OCHK_IO}/apps`, label: "Apps" },
|
|
2004
|
+
{ href: DOCS_HREF, label: "Docs" },
|
|
2005
|
+
{ href: `${OCHK_IO}/trust`, label: "Trust" },
|
|
2006
|
+
{ href: `${OCHK_IO}/about`, label: "About" }
|
|
2007
|
+
];
|
|
2008
|
+
var WORD = {
|
|
2009
|
+
live: "Live",
|
|
2010
|
+
testing: "In testing",
|
|
2011
|
+
"not-yet": "Not yet",
|
|
2012
|
+
paused: "Paused",
|
|
2013
|
+
good: "Good",
|
|
2014
|
+
caution: "Caution",
|
|
2015
|
+
refused: "Refused"
|
|
2016
|
+
};
|
|
2017
|
+
var TONE2 = {
|
|
2018
|
+
live: "success",
|
|
2019
|
+
testing: "brand",
|
|
2020
|
+
"not-yet": "muted",
|
|
2021
|
+
paused: "muted",
|
|
2022
|
+
good: "success",
|
|
2023
|
+
caution: "brand",
|
|
2024
|
+
refused: "danger"
|
|
2025
|
+
};
|
|
2026
|
+
function StatusBadge({ status, className, ...props }) {
|
|
2027
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: TONE2[status], "data-status": status, className: cn(className), ...props, children: WORD[status] });
|
|
2028
|
+
}
|
|
2029
|
+
var CARD = "group relative flex h-full flex-col rounded-[1.25rem] border border-border bg-card p-6 transition-colors hover:border-oca-hairline-strong md:p-7 has-[a:focus-visible]:ring-2 has-[a:focus-visible]:ring-ring has-[a:focus-visible]:ring-offset-2 has-[a:focus-visible]:ring-offset-background";
|
|
2030
|
+
var STRETCH = 'outline-none after:absolute after:inset-0 after:rounded-[1.25rem] after:content-[""]';
|
|
2031
|
+
var pad2 = (n) => String(n + 1).padStart(2, "0");
|
|
2032
|
+
function ProtocolGrid({
|
|
2033
|
+
protocols = PROTOCOL_ORDER,
|
|
2034
|
+
link = "page",
|
|
2035
|
+
className
|
|
2036
|
+
}) {
|
|
2037
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: cn("grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 md:gap-5", className), children: protocols.map((slug) => {
|
|
2038
|
+
const p = protocolSite(slug);
|
|
2039
|
+
const i = PROTOCOL_ORDER.indexOf(slug);
|
|
2040
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(CARD, "gap-4"), children: [
|
|
2041
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
2042
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "oca-numeral", children: [
|
|
2043
|
+
pad2(i),
|
|
2044
|
+
" ",
|
|
2045
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1.5 capitalize", children: p.verb })
|
|
2046
|
+
] }),
|
|
2047
|
+
p.status !== "live" ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: p.status }) : null
|
|
2048
|
+
] }),
|
|
2049
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-display-3", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: link === "tool" ? p.toolHref : p.pageHref, className: STRETCH, children: p.label }) }),
|
|
2050
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-body", children: p.line }),
|
|
2051
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex items-center justify-between gap-3 pt-2 text-[0.875rem] text-muted-foreground", children: [
|
|
2052
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "oca-tabular", children: [
|
|
2053
|
+
"Nostr kind ",
|
|
2054
|
+
p.kinds
|
|
2055
|
+
] }),
|
|
2056
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2057
|
+
lucideReact.ArrowUpRight,
|
|
2058
|
+
{
|
|
2059
|
+
"aria-hidden": true,
|
|
2060
|
+
className: "size-4 transition-transform duration-200 group-hover:-translate-y-0.5 group-hover:translate-x-0.5 group-hover:text-foreground"
|
|
2061
|
+
}
|
|
2062
|
+
)
|
|
2063
|
+
] })
|
|
2064
|
+
] }) }, slug);
|
|
2065
|
+
}) });
|
|
2066
|
+
}
|
|
2067
|
+
function AppCard({ name, line, href, protocols = [], status = "live", className }) {
|
|
2068
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(CARD, "gap-3", className), children: [
|
|
2069
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
2070
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-title", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: STRETCH, children: name }) }),
|
|
2071
|
+
status !== "live" ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status }) : null
|
|
2072
|
+
] }),
|
|
2073
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-body text-[0.9375rem]", children: line }),
|
|
2074
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex items-end justify-between gap-3 pt-3", children: [
|
|
2075
|
+
protocols.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "flex flex-wrap items-center gap-1.5 text-[0.8125rem] text-muted-foreground", children: [
|
|
2076
|
+
"Shows",
|
|
2077
|
+
protocols.map((p) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: "muted", children: p }, p))
|
|
2078
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
2079
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex shrink-0 items-center gap-1 text-[0.875rem] text-muted-foreground transition-colors group-hover:text-foreground", children: [
|
|
2080
|
+
href.replace(/^https?:\/\//, ""),
|
|
2081
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpRight, { "aria-hidden": true, className: "size-4" })
|
|
2082
|
+
] })
|
|
2083
|
+
] })
|
|
2084
|
+
] });
|
|
2085
|
+
}
|
|
2086
|
+
function AppGrid({
|
|
2087
|
+
group = "app",
|
|
2088
|
+
sites,
|
|
2089
|
+
className
|
|
2090
|
+
}) {
|
|
2091
|
+
const list = sites ? sites.map((slug) => FAMILY.find((s) => s.slug === slug)).filter((s) => s !== void 0) : FAMILY.filter((s) => s.group === group);
|
|
2092
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: cn("grid grid-cols-1 gap-4 sm:grid-cols-2 md:gap-5", className), children: list.map((s) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(AppCard, { name: s.label, line: s.line, href: s.href, protocols: s.protocols, status: s.status }) }, s.slug)) });
|
|
2093
|
+
}
|
|
2094
|
+
var fieldBase = [
|
|
2095
|
+
"w-full rounded-xl border border-input bg-card text-foreground placeholder:text-oca-subtle",
|
|
2096
|
+
"text-base md:text-[0.9375rem] outline-none transition-[border-color,box-shadow]",
|
|
2097
|
+
"focus:border-foreground/35 focus:ring-4 focus:ring-[color-mix(in_oklab,var(--oca-orange)_16%,transparent)]",
|
|
2098
|
+
"disabled:cursor-not-allowed disabled:opacity-55",
|
|
2099
|
+
"aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-[color-mix(in_oklab,var(--destructive)_14%,transparent)]"
|
|
2100
|
+
];
|
|
2101
|
+
var Input = react.forwardRef(function Input2({ className, type = "text", ...props }, ref) {
|
|
2102
|
+
return /* @__PURE__ */ jsxRuntime.jsx("input", { ref, type, "data-ui": "input", className: cn(fieldBase, "h-11 px-3.5", className), ...props });
|
|
2103
|
+
});
|
|
2104
|
+
var Textarea = react.forwardRef(
|
|
2105
|
+
function Textarea2({ className, ...props }, ref) {
|
|
2106
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2107
|
+
"textarea",
|
|
2108
|
+
{
|
|
2109
|
+
ref,
|
|
2110
|
+
"data-ui": "textarea",
|
|
2111
|
+
className: cn(fieldBase, "min-h-28 px-3.5 py-3 leading-relaxed", className),
|
|
2112
|
+
...props
|
|
2113
|
+
}
|
|
2114
|
+
);
|
|
2115
|
+
}
|
|
2116
|
+
);
|
|
2117
|
+
var Label = react.forwardRef(function Label2({ className, ...props }, ref) {
|
|
2118
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2119
|
+
LabelPrimitive__namespace.Root,
|
|
2120
|
+
{
|
|
2121
|
+
ref,
|
|
2122
|
+
className: cn("text-sm font-medium leading-none text-foreground", className),
|
|
2123
|
+
...props
|
|
2124
|
+
}
|
|
2125
|
+
);
|
|
2126
|
+
});
|
|
2127
|
+
function Field({ label, hint, optional, error, children, className, hideLabel, action }) {
|
|
2128
|
+
const id = react.useId();
|
|
2129
|
+
const hintId = hint ? `${id}-hint` : void 0;
|
|
2130
|
+
const errorId = error ? `${id}-error` : void 0;
|
|
2131
|
+
const describedBy = [hintId, errorId].filter(Boolean).join(" ") || void 0;
|
|
2132
|
+
const control = react.isValidElement(children) ? react.cloneElement(children, {
|
|
2133
|
+
id,
|
|
2134
|
+
"aria-describedby": describedBy,
|
|
2135
|
+
"aria-invalid": error ? true : void 0
|
|
2136
|
+
}) : children;
|
|
2137
|
+
const hintNode = hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: hintId, className: "text-[0.8125rem] leading-snug text-muted-foreground", children: hint }) : null;
|
|
2138
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
2139
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: id, className: hideLabel ? "sr-only" : "flex items-baseline gap-2", children: [
|
|
2140
|
+
label,
|
|
2141
|
+
optional ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.8125rem] font-normal text-muted-foreground", children: "Optional" }) : null
|
|
2142
|
+
] }),
|
|
2143
|
+
action ? (
|
|
2144
|
+
// The hint belongs to the input, so it sits under the input, not under the button.
|
|
2145
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-start", children: [
|
|
2146
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-2 [&>input]:w-full", children: [
|
|
2147
|
+
control,
|
|
2148
|
+
hintNode
|
|
2149
|
+
] }),
|
|
2150
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: action })
|
|
2151
|
+
] })
|
|
2152
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2153
|
+
control,
|
|
2154
|
+
hintNode
|
|
2155
|
+
] }),
|
|
2156
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, role: "alert", className: "text-[0.8125rem] leading-snug text-destructive", children: error }) : null
|
|
2157
|
+
] });
|
|
2158
|
+
}
|
|
2159
|
+
react.forwardRef(function SelectTrigger2({ className, children, ...props }, ref) {
|
|
2160
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2161
|
+
SelectPrimitive__namespace.Trigger,
|
|
2162
|
+
{
|
|
2163
|
+
ref,
|
|
2164
|
+
className: cn(fieldBase, "flex h-11 items-center justify-between gap-2 px-3.5 text-left", className),
|
|
2165
|
+
...props,
|
|
2166
|
+
children: [
|
|
2167
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children }),
|
|
2168
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4 shrink-0 text-muted-foreground" }) })
|
|
2169
|
+
]
|
|
2170
|
+
}
|
|
2171
|
+
);
|
|
2172
|
+
});
|
|
2173
|
+
react.forwardRef(function SelectContent2({ className, children, position = "popper", ...props }, ref) {
|
|
2174
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2175
|
+
SelectPrimitive__namespace.Content,
|
|
2176
|
+
{
|
|
2177
|
+
ref,
|
|
2178
|
+
position,
|
|
2179
|
+
sideOffset: 6,
|
|
2180
|
+
className: cn(
|
|
2181
|
+
"oca-animate-fade z-50 max-h-[min(24rem,var(--radix-select-content-available-height))] min-w-[var(--radix-select-trigger-width)] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-lg",
|
|
2182
|
+
className
|
|
2183
|
+
),
|
|
2184
|
+
...props,
|
|
2185
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Viewport, { children })
|
|
2186
|
+
}
|
|
2187
|
+
) });
|
|
2188
|
+
});
|
|
2189
|
+
react.forwardRef(function SelectItem2({ className, children, ...props }, ref) {
|
|
2190
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2191
|
+
SelectPrimitive__namespace.Item,
|
|
2192
|
+
{
|
|
2193
|
+
ref,
|
|
2194
|
+
className: cn(
|
|
2195
|
+
"relative flex h-10 cursor-default select-none items-center rounded-lg pl-3 pr-9 text-[0.9375rem] outline-none",
|
|
2196
|
+
"data-[highlighted]:bg-accent data-[disabled]:opacity-50",
|
|
2197
|
+
className
|
|
2198
|
+
),
|
|
2199
|
+
...props,
|
|
2200
|
+
children: [
|
|
2201
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemText, { children }),
|
|
2202
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemIndicator, { className: "absolute right-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-4" }) })
|
|
2203
|
+
]
|
|
2204
|
+
}
|
|
2205
|
+
);
|
|
2206
|
+
});
|
|
2207
|
+
react.forwardRef(function Checkbox2({ className, ...props }, ref) {
|
|
2208
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2209
|
+
CheckboxPrimitive__namespace.Root,
|
|
2210
|
+
{
|
|
2211
|
+
ref,
|
|
2212
|
+
className: cn(
|
|
2213
|
+
"peer inline-flex size-5 shrink-0 items-center justify-center rounded-[6px] border border-input bg-card",
|
|
2214
|
+
"outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
2215
|
+
"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
|
2216
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
2217
|
+
className
|
|
2218
|
+
),
|
|
2219
|
+
...props,
|
|
2220
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CheckboxPrimitive__namespace.Indicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-3.5", strokeWidth: 3 }) })
|
|
2221
|
+
}
|
|
2222
|
+
);
|
|
2223
|
+
});
|
|
2224
|
+
react.forwardRef(function Switch2({ className, ...props }, ref) {
|
|
2225
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2226
|
+
SwitchPrimitive__namespace.Root,
|
|
2227
|
+
{
|
|
2228
|
+
ref,
|
|
2229
|
+
className: cn(
|
|
2230
|
+
"peer inline-flex h-6 w-11 shrink-0 items-center rounded-full border border-transparent bg-input p-0.5",
|
|
2231
|
+
"outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
2232
|
+
// The deep orange: the track is the state, so it must clear 3:1 on a card.
|
|
2233
|
+
"data-[state=checked]:bg-oca-orange-deep disabled:cursor-not-allowed disabled:opacity-50",
|
|
2234
|
+
className
|
|
2235
|
+
),
|
|
2236
|
+
...props,
|
|
2237
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SwitchPrimitive__namespace.Thumb, { className: "pointer-events-none block size-5 rounded-full bg-white shadow-sm transition-transform data-[state=checked]:translate-x-5" })
|
|
2238
|
+
}
|
|
2239
|
+
);
|
|
2240
|
+
});
|
|
2241
|
+
react.forwardRef(function RadioGroup2({ className, ...props }, ref) {
|
|
2242
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Root, { ref, className: cn("grid gap-3", className), ...props });
|
|
2243
|
+
});
|
|
2244
|
+
react.forwardRef(function RadioGroupItem2({ className, ...props }, ref) {
|
|
2245
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2246
|
+
RadioGroupPrimitive__namespace.Item,
|
|
2247
|
+
{
|
|
2248
|
+
ref,
|
|
2249
|
+
className: cn(
|
|
2250
|
+
"inline-flex size-5 shrink-0 items-center justify-center rounded-full border border-input bg-card",
|
|
2251
|
+
"outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
2252
|
+
"data-[state=checked]:border-primary disabled:cursor-not-allowed disabled:opacity-50",
|
|
2253
|
+
className
|
|
2254
|
+
),
|
|
2255
|
+
...props,
|
|
2256
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Indicator, { className: "block size-2.5 rounded-full bg-primary" })
|
|
2257
|
+
}
|
|
2258
|
+
);
|
|
2259
|
+
});
|
|
2260
|
+
function ProtocolHero({
|
|
2261
|
+
protocol: protocol2,
|
|
2262
|
+
title,
|
|
2263
|
+
lead,
|
|
2264
|
+
actions,
|
|
2265
|
+
art,
|
|
2266
|
+
children,
|
|
2267
|
+
className
|
|
2268
|
+
}) {
|
|
2269
|
+
const p = protocolSite(protocol2);
|
|
2270
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2271
|
+
PageHero,
|
|
2272
|
+
{
|
|
2273
|
+
className,
|
|
2274
|
+
eyebrow: `Protocol \xB7 ${p.verb}`,
|
|
2275
|
+
title,
|
|
2276
|
+
lead,
|
|
2277
|
+
actions,
|
|
2278
|
+
art,
|
|
2279
|
+
children: p.status !== "live" || children ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
2280
|
+
p.status !== "live" ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: p.status }) : null,
|
|
2281
|
+
children
|
|
2282
|
+
] }) : null
|
|
2283
|
+
}
|
|
2284
|
+
);
|
|
2285
|
+
}
|
|
2286
|
+
function ProtocolNav({
|
|
2287
|
+
current,
|
|
2288
|
+
link = "page",
|
|
2289
|
+
className
|
|
2290
|
+
}) {
|
|
2291
|
+
return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Protocols", className, children: /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--background)", children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex w-max min-w-full items-center gap-6 border-b border-border", children: PROTOCOLS.map((p) => {
|
|
2292
|
+
const on = p.slug === current;
|
|
2293
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2294
|
+
"a",
|
|
2295
|
+
{
|
|
2296
|
+
href: link === "tool" ? p.toolHref : p.pageHref,
|
|
2297
|
+
"aria-current": on ? "page" : void 0,
|
|
2298
|
+
className: cn(
|
|
2299
|
+
"-mb-px inline-flex h-11 items-center border-b-2 text-[0.9375rem] transition-colors",
|
|
2300
|
+
on ? "border-foreground text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
|
|
2301
|
+
),
|
|
2302
|
+
children: p.label
|
|
2303
|
+
}
|
|
2304
|
+
) }, p.slug);
|
|
2305
|
+
}) }) }) });
|
|
2306
|
+
}
|
|
2307
|
+
function SpecCard({
|
|
2308
|
+
protocol: protocol2,
|
|
2309
|
+
version,
|
|
2310
|
+
license,
|
|
2311
|
+
vectors,
|
|
2312
|
+
size = "md",
|
|
2313
|
+
className
|
|
2314
|
+
}) {
|
|
2315
|
+
const p = protocolSite(protocol2);
|
|
2316
|
+
const repo = `oc-${p.slug}-protocol`;
|
|
2317
|
+
const facts = [
|
|
2318
|
+
["Version", version],
|
|
2319
|
+
...license ? [["Licence", license]] : [],
|
|
2320
|
+
["Nostr kind", p.kinds],
|
|
2321
|
+
...vectors !== void 0 ? [["Test vectors", String(vectors)]] : []
|
|
2322
|
+
];
|
|
2323
|
+
if (size === "sm") {
|
|
2324
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2325
|
+
"a",
|
|
2326
|
+
{
|
|
2327
|
+
href: p.specHref,
|
|
2328
|
+
className: cn(
|
|
2329
|
+
"group flex flex-wrap items-center gap-x-4 gap-y-1 rounded-2xl border border-border bg-card px-4 py-3 text-[0.875rem] transition-colors hover:border-oca-hairline-strong",
|
|
2330
|
+
className
|
|
2331
|
+
),
|
|
2332
|
+
children: [
|
|
2333
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[0.8125rem] text-foreground", children: repo }),
|
|
2334
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: facts.map(([k, v]) => k === "Version" ? `v${v}` : k === "Nostr kind" ? `kind ${v}` : v).join(" \xB7 ") }),
|
|
2335
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-auto flex items-center gap-1 text-muted-foreground group-hover:text-foreground", children: [
|
|
2336
|
+
"Read the spec ",
|
|
2337
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpRight, { "aria-hidden": true, className: "size-4" })
|
|
2338
|
+
] })
|
|
2339
|
+
]
|
|
2340
|
+
}
|
|
2341
|
+
);
|
|
2342
|
+
}
|
|
2343
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-6 rounded-[1.25rem] border border-border bg-card p-6 md:p-8", className), children: [
|
|
2344
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
2345
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
2346
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-muted-foreground", children: "The spec" }),
|
|
2347
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-title break-all font-mono text-[1.0625rem] tracking-normal", children: repo })
|
|
2348
|
+
] }),
|
|
2349
|
+
p.status !== "live" ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: p.status }) : null
|
|
2350
|
+
] }),
|
|
2351
|
+
/* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-4", children: facts.map(([k, v]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2352
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-[0.8125rem] text-muted-foreground", children: k }),
|
|
2353
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { className: "oca-tabular text-[1.0625rem]", children: v })
|
|
2354
|
+
] }, k)) }),
|
|
2355
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, variant: "secondary", size: "sm", children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: p.specHref, children: [
|
|
2356
|
+
"Read the spec ",
|
|
2357
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpRight, { "aria-hidden": true })
|
|
2358
|
+
] }) }) })
|
|
2359
|
+
] });
|
|
2360
|
+
}
|
|
2361
|
+
function VerifyBox({
|
|
2362
|
+
action,
|
|
2363
|
+
param = "q",
|
|
2364
|
+
title,
|
|
2365
|
+
description,
|
|
2366
|
+
label = "Id, envelope or link",
|
|
2367
|
+
placeholder,
|
|
2368
|
+
hint,
|
|
2369
|
+
submitLabel = "Verify",
|
|
2370
|
+
multiline = false,
|
|
2371
|
+
onVerify,
|
|
2372
|
+
className
|
|
2373
|
+
}) {
|
|
2374
|
+
const [value, setValue] = react.useState("");
|
|
2375
|
+
const submit = (e) => {
|
|
2376
|
+
if (!onVerify) return;
|
|
2377
|
+
e.preventDefault();
|
|
2378
|
+
if (value.trim()) onVerify(value.trim());
|
|
2379
|
+
};
|
|
2380
|
+
const button = /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", className: multiline ? void 0 : "w-full sm:w-auto", children: submitLabel });
|
|
2381
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2382
|
+
"form",
|
|
2383
|
+
{
|
|
2384
|
+
action,
|
|
2385
|
+
method: "get",
|
|
2386
|
+
onSubmit: submit,
|
|
2387
|
+
className: cn("flex flex-col gap-5 rounded-[1.25rem] border border-border bg-card p-6 md:p-8", className),
|
|
2388
|
+
children: [
|
|
2389
|
+
title || description ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
2390
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-title", children: title }) : null,
|
|
2391
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-body text-[0.9375rem]", children: description }) : null
|
|
2392
|
+
] }) : null,
|
|
2393
|
+
multiline ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2394
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label, hint, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2395
|
+
Textarea,
|
|
2396
|
+
{
|
|
2397
|
+
name: param,
|
|
2398
|
+
required: true,
|
|
2399
|
+
value,
|
|
2400
|
+
onChange: (e) => setValue(e.target.value),
|
|
2401
|
+
placeholder,
|
|
2402
|
+
spellCheck: false,
|
|
2403
|
+
className: "min-h-32 font-mono text-base md:text-[0.8125rem]"
|
|
2404
|
+
}
|
|
2405
|
+
) }),
|
|
2406
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: button })
|
|
2407
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(Field, { label, hint, action: button, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2408
|
+
Input,
|
|
2409
|
+
{
|
|
2410
|
+
name: param,
|
|
2411
|
+
required: true,
|
|
2412
|
+
value,
|
|
2413
|
+
onChange: (e) => setValue(e.target.value),
|
|
2414
|
+
placeholder,
|
|
2415
|
+
spellCheck: false,
|
|
2416
|
+
autoComplete: "off",
|
|
2417
|
+
className: "font-mono text-base md:text-[0.875rem]"
|
|
2418
|
+
}
|
|
2419
|
+
) })
|
|
2420
|
+
]
|
|
2421
|
+
}
|
|
2422
|
+
);
|
|
2423
|
+
}
|
|
2424
|
+
var TINT = "bg-[color-mix(in_oklab,var(--oca-orange)_9%,var(--card))]";
|
|
2425
|
+
function ComparisonTable({
|
|
2426
|
+
columns,
|
|
2427
|
+
rows,
|
|
2428
|
+
label,
|
|
2429
|
+
propertyHeading = "Property",
|
|
2430
|
+
className
|
|
2431
|
+
}) {
|
|
2432
|
+
const wide = columns.length > 3;
|
|
2433
|
+
const grid = wide ? "lg:grid lg:grid-cols-[var(--oca-compare)]" : "md:grid md:grid-cols-[var(--oca-compare)]";
|
|
2434
|
+
const desk = wide ? "lg" : "md";
|
|
2435
|
+
const style = {
|
|
2436
|
+
// The argued-for column gets a little more room: its answers carry the page.
|
|
2437
|
+
"--oca-compare": ["minmax(0, 1.4fr)", ...columns.map((c) => c.highlight ? "minmax(0, 1.3fr)" : "minmax(0, 1fr)")].join(" ")
|
|
2438
|
+
};
|
|
2439
|
+
const ordered = [...columns].sort((a, b) => Number(Boolean(b.highlight)) - Number(Boolean(a.highlight)));
|
|
2440
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("ul", { "aria-label": label, style, className: cn("divide-y divide-border rounded-[1.25rem] border border-border bg-card", className), children: [
|
|
2441
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2442
|
+
"li",
|
|
2443
|
+
{
|
|
2444
|
+
"aria-hidden": true,
|
|
2445
|
+
className: cn(
|
|
2446
|
+
"hidden gap-5 px-5 py-4 text-[0.875rem] font-medium text-muted-foreground",
|
|
2447
|
+
wide ? "lg:grid lg:px-8" : "md:grid md:px-8",
|
|
2448
|
+
grid
|
|
2449
|
+
),
|
|
2450
|
+
children: [
|
|
2451
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: propertyHeading }),
|
|
2452
|
+
columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(c.highlight && cn(TINT, "-my-4 px-4 py-4 text-oca-accent-ink")), children: c.label }, c.key))
|
|
2453
|
+
]
|
|
2454
|
+
}
|
|
2455
|
+
),
|
|
2456
|
+
rows.map((r, ri) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: cn("grid grid-cols-1 gap-3 px-5 py-5", wide ? "lg:items-start lg:gap-5 lg:px-8" : "md:items-start md:gap-5 md:px-8", grid), children: [
|
|
2457
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
2458
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-title-sm", children: r.label }),
|
|
2459
|
+
r.note ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: r.note }) : null
|
|
2460
|
+
] }),
|
|
2461
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid grid-cols-2 gap-1", desk === "lg" ? "lg:contents" : "md:contents"), children: columns.map((c) => {
|
|
2462
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2463
|
+
"div",
|
|
2464
|
+
{
|
|
2465
|
+
style: { "--oca-order": ordered.indexOf(c) },
|
|
2466
|
+
className: cn(
|
|
2467
|
+
// Two rows of the pair's grid (name, answer), so answers line up
|
|
2468
|
+
// across a pair even when one name wraps.
|
|
2469
|
+
"order-[var(--oca-order)] row-span-2 grid min-w-0 grid-rows-subgrid gap-1 rounded-xl px-3 py-2.5",
|
|
2470
|
+
desk === "lg" ? "lg:order-none lg:row-span-1 lg:flex lg:flex-col" : "md:order-none md:row-span-1 md:flex md:flex-col",
|
|
2471
|
+
c.highlight ? cn(
|
|
2472
|
+
TINT,
|
|
2473
|
+
"col-span-2",
|
|
2474
|
+
desk === "lg" ? "lg:col-span-1 lg:-my-5 lg:self-stretch lg:rounded-none lg:px-4 lg:py-5" : "md:col-span-1 md:-my-5 md:self-stretch md:rounded-none md:px-4 md:py-5"
|
|
2475
|
+
) : desk === "lg" ? "lg:p-0" : "md:p-0"
|
|
2476
|
+
),
|
|
2477
|
+
children: [
|
|
2478
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2479
|
+
"span",
|
|
2480
|
+
{
|
|
2481
|
+
className: cn(
|
|
2482
|
+
"text-[0.8125rem]",
|
|
2483
|
+
c.highlight ? "text-oca-accent-ink" : "text-muted-foreground",
|
|
2484
|
+
desk === "lg" ? "lg:sr-only" : "md:sr-only"
|
|
2485
|
+
),
|
|
2486
|
+
children: c.label
|
|
2487
|
+
}
|
|
2488
|
+
),
|
|
2489
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[0.9375rem]", c.highlight && "font-medium"), children: r.values[c.key] ?? "\u2014" })
|
|
2490
|
+
]
|
|
2491
|
+
},
|
|
2492
|
+
c.key
|
|
2493
|
+
);
|
|
2494
|
+
}) })
|
|
2495
|
+
] }, ri))
|
|
2496
|
+
] });
|
|
2497
|
+
}
|
|
2498
|
+
var CHECK = {
|
|
2499
|
+
ok: { word: "Passed", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleCheck, {}), tone: "text-success" },
|
|
2500
|
+
fail: { word: "Failed", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleX, {}), tone: "text-destructive" },
|
|
2501
|
+
pending: { word: "Pending", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, {}), tone: "text-oca-accent-ink" },
|
|
2502
|
+
skipped: { word: "Skipped", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleMinus, {}), tone: "text-muted-foreground" },
|
|
2503
|
+
unchecked: { word: "Not checked", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleDashed, {}), tone: "text-oca-subtle" }
|
|
2504
|
+
};
|
|
2505
|
+
function VerifyReport({
|
|
2506
|
+
verdict,
|
|
2507
|
+
title,
|
|
2508
|
+
summary,
|
|
2509
|
+
checks,
|
|
2510
|
+
facts,
|
|
2511
|
+
notChecked,
|
|
2512
|
+
actions,
|
|
2513
|
+
className
|
|
2514
|
+
}) {
|
|
2515
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2516
|
+
"section",
|
|
2517
|
+
{
|
|
2518
|
+
"aria-label": "Verification result",
|
|
2519
|
+
className: cn("overflow-hidden rounded-[1.25rem] border border-border bg-card", className),
|
|
2520
|
+
children: [
|
|
2521
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col items-start gap-3 p-6 md:p-8", children: [
|
|
2522
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: verdict }),
|
|
2523
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "oca-display-3", children: title }),
|
|
2524
|
+
summary ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-body max-w-[40rem]", children: summary }) : null
|
|
2525
|
+
] }),
|
|
2526
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": "Checks", className: "divide-y divide-border border-t border-border", children: checks.map((c, i) => {
|
|
2527
|
+
const k = CHECK[c.state];
|
|
2528
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start gap-3 px-6 py-3.5 md:px-8", children: [
|
|
2529
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: cn("mt-0.5 shrink-0 [&_svg]:size-[1.125rem]", k.tone), children: k.icon }),
|
|
2530
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5 sm:flex-row sm:items-baseline sm:justify-between sm:gap-6", children: [
|
|
2531
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
2532
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9375rem]", children: c.label }),
|
|
2533
|
+
c.note ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-words text-[0.8125rem] leading-snug text-muted-foreground", children: c.note }) : null
|
|
2534
|
+
] }),
|
|
2535
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2536
|
+
"span",
|
|
2537
|
+
{
|
|
2538
|
+
className: cn(
|
|
2539
|
+
"shrink-0 text-[0.8125rem]",
|
|
2540
|
+
c.state === "fail" ? "text-destructive" : "text-muted-foreground"
|
|
2541
|
+
),
|
|
2542
|
+
children: k.word
|
|
2543
|
+
}
|
|
2544
|
+
)
|
|
2545
|
+
] })
|
|
2546
|
+
] }, i);
|
|
2547
|
+
}) }),
|
|
2548
|
+
facts && facts.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(KeyValueList, { items: facts, className: "rounded-none border-x-0 border-b-0 bg-transparent [&>div]:px-6 md:[&>div]:px-8" }) : null,
|
|
2549
|
+
notChecked && notChecked.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 border-t border-border bg-muted/50 px-6 py-5 md:px-8", children: [
|
|
2550
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] font-medium", children: "What this did not check" }),
|
|
2551
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex list-disc flex-col gap-1 pl-5 text-[0.875rem] leading-relaxed text-muted-foreground", children: notChecked.map((n, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: n }, i)) })
|
|
2552
|
+
] }) : null,
|
|
2553
|
+
actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-3 border-t border-border px-6 py-5 md:px-8", children: actions }) : null
|
|
2554
|
+
]
|
|
2555
|
+
}
|
|
2556
|
+
);
|
|
2557
|
+
}
|
|
2558
|
+
function SignMessage({
|
|
2559
|
+
lead,
|
|
2560
|
+
address,
|
|
2561
|
+
message,
|
|
2562
|
+
wallets,
|
|
2563
|
+
busy = false,
|
|
2564
|
+
error,
|
|
2565
|
+
submitLabel = "Confirm",
|
|
2566
|
+
secondary,
|
|
2567
|
+
onSignature,
|
|
2568
|
+
className
|
|
2569
|
+
}) {
|
|
2570
|
+
const [pasted, setPasted] = react.useState("");
|
|
2571
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-5", className), children: [
|
|
2572
|
+
lead ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.9375rem] leading-relaxed", children: lead }) : null,
|
|
2573
|
+
wallets ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2574
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: wallets }),
|
|
2575
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 text-[0.8125rem] text-muted-foreground", children: [
|
|
2576
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-px flex-1 bg-border" }),
|
|
2577
|
+
"or sign it in any wallet",
|
|
2578
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-px flex-1 bg-border" })
|
|
2579
|
+
] })
|
|
2580
|
+
] }) : null,
|
|
2581
|
+
/* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { code: message, caption: "Message to sign" }),
|
|
2582
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2583
|
+
"form",
|
|
2584
|
+
{
|
|
2585
|
+
className: "flex flex-col gap-4",
|
|
2586
|
+
onSubmit: (e) => {
|
|
2587
|
+
e.preventDefault();
|
|
2588
|
+
if (pasted.trim()) onSignature(pasted.trim());
|
|
2589
|
+
},
|
|
2590
|
+
children: [
|
|
2591
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2592
|
+
Field,
|
|
2593
|
+
{
|
|
2594
|
+
label: "Signature",
|
|
2595
|
+
error,
|
|
2596
|
+
hint: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2597
|
+
"From your wallet\u2019s \u201Csign message\u201D (BIP-322), signed by",
|
|
2598
|
+
" ",
|
|
2599
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-all font-mono", children: address }),
|
|
2600
|
+
"."
|
|
2601
|
+
] }),
|
|
2602
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2603
|
+
Textarea,
|
|
2604
|
+
{
|
|
2605
|
+
value: pasted,
|
|
2606
|
+
onChange: (e) => setPasted(e.target.value),
|
|
2607
|
+
rows: 3,
|
|
2608
|
+
spellCheck: false,
|
|
2609
|
+
className: "min-h-24 font-mono text-base md:text-[0.8125rem]"
|
|
2610
|
+
}
|
|
2611
|
+
)
|
|
2612
|
+
}
|
|
2613
|
+
),
|
|
2614
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
2615
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", loading: busy, disabled: !pasted.trim(), children: submitLabel }),
|
|
2616
|
+
secondary
|
|
2617
|
+
] })
|
|
2618
|
+
]
|
|
2619
|
+
}
|
|
2620
|
+
)
|
|
2621
|
+
] });
|
|
2622
|
+
}
|
|
1458
2623
|
|
|
1459
2624
|
exports.Accent = Accent;
|
|
1460
2625
|
exports.ActivityList = ActivityList;
|
|
2626
|
+
exports.AppCard = AppCard;
|
|
2627
|
+
exports.AppGrid = AppGrid;
|
|
1461
2628
|
exports.BrowserFrame = BrowserFrame;
|
|
2629
|
+
exports.Closing = Closing;
|
|
1462
2630
|
exports.CodeBlock = CodeBlock;
|
|
2631
|
+
exports.ComparisonTable = ComparisonTable;
|
|
1463
2632
|
exports.Container = Container;
|
|
1464
2633
|
exports.CopyButton = CopyButton;
|
|
1465
2634
|
exports.DataTable = DataTable;
|
|
@@ -1468,13 +2637,19 @@ exports.DocHeader = DocHeader;
|
|
|
1468
2637
|
exports.DocLayout = DocLayout;
|
|
1469
2638
|
exports.EmptyLine = EmptyLine;
|
|
1470
2639
|
exports.EmptyState = EmptyState;
|
|
2640
|
+
exports.EndpointList = EndpointList;
|
|
1471
2641
|
exports.ErrorBoundary = ErrorBoundary;
|
|
2642
|
+
exports.ErrorPage = ErrorPage;
|
|
1472
2643
|
exports.Eyebrow = Eyebrow;
|
|
2644
|
+
exports.FactBlock = FactBlock;
|
|
2645
|
+
exports.FactRows = FactRows;
|
|
2646
|
+
exports.Faq = Faq;
|
|
1473
2647
|
exports.FloatChip = FloatChip;
|
|
1474
2648
|
exports.Footnote = Footnote;
|
|
1475
2649
|
exports.HashChip = HashChip;
|
|
1476
2650
|
exports.KeyValueList = KeyValueList;
|
|
1477
2651
|
exports.Lead = Lead;
|
|
2652
|
+
exports.LegalDocument = LegalDocument;
|
|
1478
2653
|
exports.LoadingBlock = LoadingBlock;
|
|
1479
2654
|
exports.Monogram = Monogram;
|
|
1480
2655
|
exports.Notice = Notice;
|
|
@@ -1483,20 +2658,30 @@ exports.PageHeader = PageHeader;
|
|
|
1483
2658
|
exports.PageHero = PageHero;
|
|
1484
2659
|
exports.PhoneFrame = PhoneFrame;
|
|
1485
2660
|
exports.ProgressSteps = ProgressSteps;
|
|
2661
|
+
exports.ProofStrip = ProofStrip;
|
|
1486
2662
|
exports.Prose = Prose;
|
|
2663
|
+
exports.ProtocolGrid = ProtocolGrid;
|
|
2664
|
+
exports.ProtocolHero = ProtocolHero;
|
|
2665
|
+
exports.ProtocolNav = ProtocolNav;
|
|
1487
2666
|
exports.Reveal = Reveal;
|
|
1488
2667
|
exports.Sats = Sats;
|
|
1489
2668
|
exports.SatsFigure = SatsFigure;
|
|
1490
2669
|
exports.ScrollStory = ScrollStory;
|
|
1491
2670
|
exports.Section = Section;
|
|
2671
|
+
exports.SectionHeading = SectionHeading;
|
|
1492
2672
|
exports.SectionIntro = SectionIntro;
|
|
2673
|
+
exports.SignMessage = SignMessage;
|
|
2674
|
+
exports.SpecCard = SpecCard;
|
|
1493
2675
|
exports.SplitBar = SplitBar;
|
|
1494
2676
|
exports.StatCard = StatCard;
|
|
1495
2677
|
exports.StatGrid = StatGrid;
|
|
1496
2678
|
exports.StepGrid = StepGrid;
|
|
2679
|
+
exports.TextLink = TextLink;
|
|
1497
2680
|
exports.Ticker = Ticker;
|
|
1498
2681
|
exports.TruthTable = TruthTable;
|
|
1499
2682
|
exports.UsdApprox = UsdApprox;
|
|
2683
|
+
exports.VerifyBox = VerifyBox;
|
|
2684
|
+
exports.VerifyReport = VerifyReport;
|
|
1500
2685
|
exports.monogramGround = monogramGround;
|
|
1501
2686
|
exports.monogramLetter = monogramLetter;
|
|
1502
2687
|
exports.satsText = satsText;
|