@orangecheck/app-design 1.4.0 → 1.5.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.
Files changed (43) hide show
  1. package/dist/chrome.d.mts +5 -4
  2. package/dist/chrome.d.ts +5 -4
  3. package/dist/chrome.js +171 -40
  4. package/dist/chrome.js.map +1 -1
  5. package/dist/chrome.mjs +172 -41
  6. package/dist/chrome.mjs.map +1 -1
  7. package/dist/components.d.mts +46 -9
  8. package/dist/components.d.ts +46 -9
  9. package/dist/components.js +334 -167
  10. package/dist/components.js.map +1 -1
  11. package/dist/components.mjs +333 -170
  12. package/dist/components.mjs.map +1 -1
  13. package/dist/{docs-BB9gK4KF.d.ts → docs-ByUx4t-D.d.ts} +2 -1
  14. package/dist/{docs-D-T-nHiu.d.mts → docs-CFE5mU_6.d.mts} +2 -1
  15. package/dist/index.d.mts +4 -4
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.js +572 -244
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +570 -246
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/mdx.d.mts +1 -1
  22. package/dist/mdx.d.ts +1 -1
  23. package/dist/mdx.js +7 -2
  24. package/dist/mdx.js.map +1 -1
  25. package/dist/mdx.mjs +7 -2
  26. package/dist/mdx.mjs.map +1 -1
  27. package/dist/primitives.d.mts +4 -3
  28. package/dist/primitives.d.ts +4 -3
  29. package/dist/primitives.js +37 -1
  30. package/dist/primitives.js.map +1 -1
  31. package/dist/primitives.mjs +37 -1
  32. package/dist/primitives.mjs.map +1 -1
  33. package/dist/session.d.mts +3 -3
  34. package/dist/session.d.ts +3 -3
  35. package/dist/session.js +1 -1
  36. package/dist/session.js.map +1 -1
  37. package/dist/session.mjs +1 -1
  38. package/dist/session.mjs.map +1 -1
  39. package/dist/{tool-shell-D8Q8XX11.d.mts → tool-shell-CQZNRUgH.d.mts} +8 -4
  40. package/dist/{tool-shell-gmlj47Ie.d.ts → tool-shell-CRmceGrV.d.ts} +8 -4
  41. package/dist/{tools-DFIxIj5p.d.mts → tools-Bg1gi2HO.d.mts} +1 -1
  42. package/dist/{tools-BggNN5DV.d.ts → tools-Bw7RhO92.d.ts} +1 -1
  43. package/package.json +3 -2
@@ -9,6 +9,7 @@ var TabsPrimitive = require('@radix-ui/react-tabs');
9
9
  var lucideReact = require('lucide-react');
10
10
  var reactSlot = require('@radix-ui/react-slot');
11
11
  var SeparatorPrimitive = require('@radix-ui/react-separator');
12
+ require('next-themes');
12
13
  require('sonner');
13
14
  var Link = require('next/link');
14
15
  var router = require('next/compat/router');
@@ -563,7 +564,7 @@ var JS_TAG = /<\/?(?=[A-Za-z])/y;
563
564
  var JS_TAG_NAME = /[A-Za-z][\w$.:-]*/y;
564
565
  var JS_PUNCT = /=>|\.\.\.|[{}()[\];,.<>=+\-*/%!?:&|^~#]/y;
565
566
  var JSX_BEFORE = /* @__PURE__ */ new Set(["(", ",", "=", "?", ":", "{", "[", ";", ">", "&&", "||", "=>", "return"]);
566
- function scanJs(src, emit, jsx35) {
567
+ function scanJs(src, emit, jsx36) {
567
568
  let i = 0;
568
569
  let prev = "";
569
570
  let tagDepth = 0;
@@ -589,7 +590,7 @@ function scanJs(src, emit, jsx35) {
589
590
  sig('"');
590
591
  continue;
591
592
  }
592
- if (jsx35 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
593
+ if (jsx36 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
593
594
  const name = at(JS_TAG_NAME, src, i + m.length);
594
595
  if (name) {
595
596
  emit(m);
@@ -601,7 +602,7 @@ function scanJs(src, emit, jsx35) {
601
602
  continue;
602
603
  }
603
604
  }
604
- if (jsx35 && tagDepth > 0 && braceInTag === 0) {
605
+ if (jsx36 && tagDepth > 0 && braceInTag === 0) {
605
606
  if (src.startsWith("/>", i) || src[i] === ">") {
606
607
  const close = src[i] === ">" ? ">" : "/>";
607
608
  emit(close);
@@ -621,7 +622,7 @@ function scanJs(src, emit, jsx35) {
621
622
  continue;
622
623
  }
623
624
  if (src[i] === "{") braceInTag = 1;
624
- } else if (jsx35 && tagDepth > 0 && braceInTag > 0) {
625
+ } else if (jsx36 && tagDepth > 0 && braceInTag > 0) {
625
626
  if (src[i] === "{") braceInTag++;
626
627
  else if (src[i] === "}") braceInTag--;
627
628
  }
@@ -1737,7 +1738,8 @@ function Well({
1737
1738
  lines,
1738
1739
  maxLines,
1739
1740
  diff,
1740
- lineNumbers
1741
+ lineNumbers,
1742
+ wrap
1741
1743
  }) {
1742
1744
  const foldable = maxLines !== void 0 && lines > maxLines + 2;
1743
1745
  const [open, setOpen] = react.useState(false);
@@ -1756,7 +1758,8 @@ function Well({
1756
1758
  "data-diff": diff ? "" : void 0,
1757
1759
  "data-line-numbers": lineNumbers ? "" : void 0,
1758
1760
  className: cn(
1759
- "oca-code w-max min-w-full py-4 font-mono text-[0.875rem] leading-[1.625] text-oca-ink-muted [font-variant-ligatures:none]",
1761
+ "oca-code py-4 font-mono text-[0.875rem] leading-[1.625] text-oca-ink-muted [font-variant-ligatures:none]",
1762
+ wrap ? "whitespace-pre-wrap break-all" : "w-max min-w-full",
1760
1763
  !lined && "px-5"
1761
1764
  ),
1762
1765
  children: lined ? /* @__PURE__ */ jsxRuntime.jsx("code", { className: "block", "data-lang": lang, dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ jsxRuntime.jsx("code", { className: "block", "data-lang": lang, children })
@@ -1798,6 +1801,7 @@ function CodeBlock({
1798
1801
  highlight: marks,
1799
1802
  diff,
1800
1803
  lineNumbers,
1804
+ wrap,
1801
1805
  actions,
1802
1806
  className
1803
1807
  }) {
@@ -1829,6 +1833,7 @@ function CodeBlock({
1829
1833
  maxLines,
1830
1834
  diff: prepared ? prepared.diff : isDiff,
1831
1835
  lineNumbers,
1836
+ wrap,
1832
1837
  children
1833
1838
  }
1834
1839
  )
@@ -2331,6 +2336,133 @@ function MarkOutline({ className }) {
2331
2336
  points
2332
2337
  )) });
2333
2338
  }
2339
+
2340
+ // src/family/index.ts
2341
+ var OCHK_IO = "https://ochk.io";
2342
+ var DOCS_HREF = `${OCHK_IO}/docs`;
2343
+ function protocol(slug, verb, line, kinds) {
2344
+ return {
2345
+ slug,
2346
+ label: slug,
2347
+ href: `${OCHK_IO}/${slug}`,
2348
+ group: "protocol",
2349
+ line,
2350
+ status: "live",
2351
+ verb,
2352
+ pageHref: `${OCHK_IO}/${slug}`,
2353
+ toolHref: `https://${slug}.ochk.io`,
2354
+ specHref: `https://github.com/orangecheck/oc-${slug}-protocol`,
2355
+ kinds
2356
+ };
2357
+ }
2358
+ var PROTOCOLS = [
2359
+ protocol("attest", "identity", "Show that an address holds bitcoin, and for how long.", "30078"),
2360
+ protocol("lock", "confidentiality", "Encrypt to a Bitcoin address, so only its holder can open it.", "30078"),
2361
+ protocol("vote", "legitimacy", "Polls weighed in sats, that anyone can tally.", "30080\u201330082"),
2362
+ protocol("stamp", "provenance", "Prove who signed something, and when.", "30083"),
2363
+ protocol("agent", "authority", "Give software scoped, revocable permission to act for you.", "30083\u201330086"),
2364
+ protocol("pledge", "commitment", "Make a promise with bitcoin behind it, on a public record.", "30078")
2365
+ ];
2366
+ var PROTOCOL_ORDER = PROTOCOLS.map((p) => p.slug);
2367
+ var FAMILY = [
2368
+ {
2369
+ slug: "home",
2370
+ label: "ochk.io",
2371
+ href: OCHK_IO,
2372
+ group: "orangecheck",
2373
+ line: "The open protocols, and the company behind them.",
2374
+ status: "live"
2375
+ },
2376
+ {
2377
+ slug: "me",
2378
+ label: "ochk.app",
2379
+ href: "https://ochk.app",
2380
+ group: "orangecheck",
2381
+ line: "One account, with Bitcoin behind it.",
2382
+ status: "testing"
2383
+ },
2384
+ {
2385
+ slug: "docs",
2386
+ label: "docs",
2387
+ href: DOCS_HREF,
2388
+ group: "orangecheck",
2389
+ line: "Specs, SDKs and guides for every protocol.",
2390
+ status: "live"
2391
+ },
2392
+ ...PROTOCOLS,
2393
+ {
2394
+ slug: "vault",
2395
+ label: "vault",
2396
+ href: "https://vault.ochk.io",
2397
+ group: "app",
2398
+ line: "A password manager, encrypted in your browser.",
2399
+ status: "live",
2400
+ protocols: ["lock"]
2401
+ },
2402
+ {
2403
+ slug: "chat",
2404
+ label: "chat",
2405
+ href: "https://chat.ochk.io",
2406
+ group: "app",
2407
+ line: "Messages only the holder of a Bitcoin address can read.",
2408
+ status: "testing",
2409
+ protocols: ["lock"]
2410
+ },
2411
+ {
2412
+ slug: "cosign",
2413
+ label: "cosign",
2414
+ href: "https://cosign.ochk.io",
2415
+ group: "app",
2416
+ line: "Builders find co-founders and backers.",
2417
+ status: "testing",
2418
+ // Signs in with an orangecheck account and a wallet; uses none of the six directly.
2419
+ protocols: []
2420
+ },
2421
+ {
2422
+ slug: "me-demo",
2423
+ // "demo", not the made-up app's own name, so nobody takes it for ours.
2424
+ label: "demo",
2425
+ href: "https://me-demo.ochk.io",
2426
+ group: "app",
2427
+ line: "Lumen Notes, a made-up app that signs in with orangecheck.",
2428
+ status: "live"
2429
+ },
2430
+ {
2431
+ slug: "globe",
2432
+ label: "globe",
2433
+ href: "https://globe.ochk.io",
2434
+ group: "public-good",
2435
+ line: "The Bitcoin network, live, on a globe.",
2436
+ status: "live"
2437
+ },
2438
+ {
2439
+ slug: "btc",
2440
+ label: "btc",
2441
+ href: "https://btc.ochk.io",
2442
+ group: "public-good",
2443
+ line: "A free desk for reading the Bitcoin market.",
2444
+ status: "live"
2445
+ }
2446
+ ];
2447
+ var BY_SLUG = new Map(FAMILY.map((s) => [s.slug, s]));
2448
+ function protocolSite(slug) {
2449
+ return BY_SLUG.get(slug);
2450
+ }
2451
+ [
2452
+ {
2453
+ href: `${OCHK_IO}/protocols`,
2454
+ label: "Protocols",
2455
+ children: PROTOCOLS.map((p) => ({ href: p.pageHref, label: p.label, description: p.line }))
2456
+ },
2457
+ { href: `${OCHK_IO}/apps`, label: "Apps" },
2458
+ { href: DOCS_HREF, label: "Docs" },
2459
+ { href: `${OCHK_IO}/trust`, label: "Trust" },
2460
+ { href: `${OCHK_IO}/about`, label: "About" }
2461
+ ];
2462
+ var SiteHomeContext = sharedContext("site-home", void 0);
2463
+ function useSiteHome() {
2464
+ return react.useContext(SiteHomeContext);
2465
+ }
2334
2466
  var WORDS = {
2335
2467
  404: {
2336
2468
  name: "Not found",
@@ -2348,10 +2480,13 @@ function ErrorPage({
2348
2480
  title,
2349
2481
  detail,
2350
2482
  actions,
2351
- home = "/",
2483
+ home,
2484
+ protocol: protocol2,
2352
2485
  art,
2353
2486
  className
2354
2487
  }) {
2488
+ const shellHome = useSiteHome();
2489
+ const homeHref = home ?? (protocol2 ? protocolSite(protocol2).pageHref : shellHome ?? OCHK_IO);
2355
2490
  const words = WORDS[code] ?? (code >= 500 ? WORDS[500] : WORDS[404]);
2356
2491
  const server = code >= 500;
2357
2492
  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: [
@@ -2365,12 +2500,137 @@ function ErrorPage({
2365
2500
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-lead oca-enter [--enter-delay:150ms]", children: detail ?? words.detail }),
2366
2501
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-enter flex flex-wrap gap-3 [--enter-delay:230ms]", children: actions ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2367
2502
  server ? /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => window.location.reload(), children: "Try again" }) : null,
2368
- /* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, variant: server ? "secondary" : "primary", children: /* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href: home, children: "Go home" }) })
2503
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, variant: server ? "secondary" : "primary", children: /* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href: homeHref, children: "Go home" }) })
2369
2504
  ] }) })
2370
2505
  ] }),
2371
2506
  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
2372
2507
  ] }) });
2373
2508
  }
2509
+ function onSecond(tick) {
2510
+ const id = setInterval(tick, 1e3);
2511
+ return () => clearInterval(id);
2512
+ }
2513
+ var nowSeconds = () => Math.floor(Date.now() / 1e3);
2514
+ function CountdownRing({
2515
+ period,
2516
+ remaining,
2517
+ warnAt = 5,
2518
+ size = 18,
2519
+ showSeconds = true,
2520
+ className
2521
+ }) {
2522
+ const now = react.useSyncExternalStore(onSecond, nowSeconds, () => null);
2523
+ const left = remaining ?? (now === null ? null : period - now % period);
2524
+ const share = left === null ? 1 : Math.max(0, Math.min(1, left / period));
2525
+ const warn = left !== null && left <= warnAt;
2526
+ const r = size / 2 - 1.5;
2527
+ const c = 2 * Math.PI * r;
2528
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2529
+ "span",
2530
+ {
2531
+ role: "timer",
2532
+ "aria-label": left === null ? void 0 : `${left} second${left === 1 ? "" : "s"} left`,
2533
+ className: cn("inline-flex items-center gap-1.5", warn ? "text-destructive" : "text-muted-foreground", className),
2534
+ children: [
2535
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { "aria-hidden": true, width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", children: [
2536
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: size / 2, cy: size / 2, r, fill: "none", stroke: "var(--border)", strokeWidth: 2 }),
2537
+ /* @__PURE__ */ jsxRuntime.jsx(
2538
+ "circle",
2539
+ {
2540
+ cx: size / 2,
2541
+ cy: size / 2,
2542
+ r,
2543
+ fill: "none",
2544
+ stroke: "currentColor",
2545
+ strokeWidth: 2,
2546
+ strokeLinecap: "round",
2547
+ strokeDasharray: c,
2548
+ strokeDashoffset: c * (1 - share),
2549
+ className: cn(left !== null && left < period && "transition-[stroke-dashoffset] duration-1000 ease-linear motion-reduce:transition-none")
2550
+ }
2551
+ )
2552
+ ] }),
2553
+ showSeconds && left !== null ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[0.8125rem] oca-tabular", children: [
2554
+ left,
2555
+ "s"
2556
+ ] }) : null
2557
+ ]
2558
+ }
2559
+ );
2560
+ }
2561
+ function PlanCard({
2562
+ name,
2563
+ subtitle,
2564
+ price,
2565
+ period,
2566
+ footnote,
2567
+ features = [],
2568
+ action,
2569
+ badge,
2570
+ badgeTone = "neutral",
2571
+ highlight: highlight2 = false,
2572
+ className
2573
+ }) {
2574
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2575
+ "section",
2576
+ {
2577
+ className: cn(
2578
+ "flex h-full flex-col gap-5 rounded-[1.25rem] border bg-card p-6",
2579
+ highlight2 ? "border-foreground shadow-sm ring-1 ring-foreground" : "border-border",
2580
+ className
2581
+ ),
2582
+ children: [
2583
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
2584
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
2585
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[1.0625rem] font-medium leading-snug", children: name }),
2586
+ badge ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: badgeTone, children: badge }) : null
2587
+ ] }),
2588
+ subtitle ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: subtitle }) : null
2589
+ ] }),
2590
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2591
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "flex flex-wrap items-baseline gap-x-1.5", children: [
2592
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-display-3 oca-tabular", children: price }),
2593
+ period ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9375rem] text-muted-foreground", children: period }) : null
2594
+ ] }),
2595
+ footnote ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.8125rem] text-muted-foreground", children: footnote }) : null
2596
+ ] }),
2597
+ features.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-2.5 text-[0.9375rem]", children: features.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start gap-2.5", children: [
2598
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { "aria-hidden": true, className: "mt-1 size-4 shrink-0 text-muted-foreground" }),
2599
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0", children: f })
2600
+ ] }, i)) }) : null,
2601
+ action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col pt-1 [&>*]:w-full", children: action }) : null
2602
+ ]
2603
+ }
2604
+ );
2605
+ }
2606
+ function LockedPreview({
2607
+ title,
2608
+ description,
2609
+ action,
2610
+ children,
2611
+ className
2612
+ }) {
2613
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", className), children: [
2614
+ children ? /* @__PURE__ */ jsxRuntime.jsx(
2615
+ "div",
2616
+ {
2617
+ inert: true,
2618
+ "aria-hidden": true,
2619
+ "data-oca-locked": "",
2620
+ className: "pointer-events-none max-h-[28rem] select-none overflow-hidden [mask-image:linear-gradient(to_bottom,#000_25%,transparent_85%)]",
2621
+ children
2622
+ }
2623
+ ) : null,
2624
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative mx-auto flex max-w-md flex-col items-center gap-4 rounded-[1.25rem] border border-border bg-card px-6 py-7 text-center shadow-sm", children && "-mt-40"), children: [
2625
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "flex size-10 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { className: "size-[1.125rem]" }) }),
2626
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
2627
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[1.0625rem] font-medium leading-snug", children: title }),
2628
+ description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.9375rem] leading-snug text-muted-foreground", children: description }) : null
2629
+ ] }),
2630
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-2", children: action })
2631
+ ] })
2632
+ ] });
2633
+ }
2374
2634
  function IsoCheck({ size = 360, settle = false, shadow = true, tilt = false, title, className }) {
2375
2635
  const ref = react.useRef(null);
2376
2636
  react.useEffect(() => {
@@ -2716,129 +2976,6 @@ function LegalDocument({ doc, className }) {
2716
2976
  }
2717
2977
  );
2718
2978
  }
2719
-
2720
- // src/family/index.ts
2721
- var OCHK_IO = "https://ochk.io";
2722
- var DOCS_HREF = `${OCHK_IO}/docs`;
2723
- function protocol(slug, verb, line, kinds) {
2724
- return {
2725
- slug,
2726
- label: slug,
2727
- href: `${OCHK_IO}/${slug}`,
2728
- group: "protocol",
2729
- line,
2730
- status: "live",
2731
- verb,
2732
- pageHref: `${OCHK_IO}/${slug}`,
2733
- toolHref: `https://${slug}.ochk.io`,
2734
- specHref: `https://github.com/orangecheck/oc-${slug}-protocol`,
2735
- kinds
2736
- };
2737
- }
2738
- var PROTOCOLS = [
2739
- protocol("attest", "identity", "Show that an address holds bitcoin, and for how long.", "30078"),
2740
- protocol("lock", "confidentiality", "Encrypt to a Bitcoin address, so only its holder can open it.", "30078"),
2741
- protocol("vote", "legitimacy", "Polls weighed in sats, that anyone can tally.", "30080\u201330082"),
2742
- protocol("stamp", "provenance", "Prove who signed something, and when.", "30083"),
2743
- protocol("agent", "authority", "Give software scoped, revocable permission to act for you.", "30083\u201330086"),
2744
- protocol("pledge", "commitment", "Make a promise with bitcoin behind it, on a public record.", "30078")
2745
- ];
2746
- var PROTOCOL_ORDER = PROTOCOLS.map((p) => p.slug);
2747
- var FAMILY = [
2748
- {
2749
- slug: "home",
2750
- label: "ochk.io",
2751
- href: OCHK_IO,
2752
- group: "orangecheck",
2753
- line: "The open protocols, and the company behind them.",
2754
- status: "live"
2755
- },
2756
- {
2757
- slug: "me",
2758
- label: "ochk.app",
2759
- href: "https://ochk.app",
2760
- group: "orangecheck",
2761
- line: "One account, with Bitcoin behind it.",
2762
- status: "testing"
2763
- },
2764
- {
2765
- slug: "docs",
2766
- label: "docs",
2767
- href: DOCS_HREF,
2768
- group: "orangecheck",
2769
- line: "Specs, SDKs and guides for every protocol.",
2770
- status: "live"
2771
- },
2772
- ...PROTOCOLS,
2773
- {
2774
- slug: "vault",
2775
- label: "vault",
2776
- href: "https://vault.ochk.io",
2777
- group: "app",
2778
- line: "A password manager, encrypted in your browser.",
2779
- status: "live",
2780
- protocols: ["lock"]
2781
- },
2782
- {
2783
- slug: "chat",
2784
- label: "chat",
2785
- href: "https://chat.ochk.io",
2786
- group: "app",
2787
- line: "Messages only the holder of a Bitcoin address can read.",
2788
- status: "testing",
2789
- protocols: ["lock"]
2790
- },
2791
- {
2792
- slug: "cosign",
2793
- label: "cosign",
2794
- href: "https://cosign.ochk.io",
2795
- group: "app",
2796
- line: "Builders find co-founders and backers.",
2797
- status: "testing",
2798
- // Signs in with an orangecheck account and a wallet; uses none of the six directly.
2799
- protocols: []
2800
- },
2801
- {
2802
- slug: "me-demo",
2803
- // "demo", not the made-up app's own name, so nobody takes it for ours.
2804
- label: "demo",
2805
- href: "https://me-demo.ochk.io",
2806
- group: "app",
2807
- line: "Lumen Notes, a made-up app that signs in with orangecheck.",
2808
- status: "live"
2809
- },
2810
- {
2811
- slug: "globe",
2812
- label: "globe",
2813
- href: "https://globe.ochk.io",
2814
- group: "public-good",
2815
- line: "The Bitcoin network, live, on a globe.",
2816
- status: "live"
2817
- },
2818
- {
2819
- slug: "btc",
2820
- label: "btc",
2821
- href: "https://btc.ochk.io",
2822
- group: "public-good",
2823
- line: "A free desk for reading the Bitcoin market.",
2824
- status: "live"
2825
- }
2826
- ];
2827
- var BY_SLUG = new Map(FAMILY.map((s) => [s.slug, s]));
2828
- function protocolSite(slug) {
2829
- return BY_SLUG.get(slug);
2830
- }
2831
- [
2832
- {
2833
- href: `${OCHK_IO}/protocols`,
2834
- label: "Protocols",
2835
- children: PROTOCOLS.map((p) => ({ href: p.pageHref, label: p.label, description: p.line }))
2836
- },
2837
- { href: `${OCHK_IO}/apps`, label: "Apps" },
2838
- { href: DOCS_HREF, label: "Docs" },
2839
- { href: `${OCHK_IO}/trust`, label: "Trust" },
2840
- { href: `${OCHK_IO}/about`, label: "About" }
2841
- ];
2842
2979
  var InDocsContext = sharedContext("in-docs", false);
2843
2980
  function useInDocs() {
2844
2981
  return react.useContext(InDocsContext);
@@ -3853,6 +3990,7 @@ function SignMessage({
3853
3990
  error,
3854
3991
  submitLabel = "Confirm",
3855
3992
  secondary,
3993
+ scheme = "bip322",
3856
3994
  onSignature,
3857
3995
  className
3858
3996
  }) {
@@ -3867,7 +4005,7 @@ function SignMessage({
3867
4005
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-px flex-1 bg-border" })
3868
4006
  ] })
3869
4007
  ] }) : null,
3870
- /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { code: message, caption: "Message to sign" }),
4008
+ /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { code: message, caption: "Message to sign", wrap: true }),
3871
4009
  /* @__PURE__ */ jsxRuntime.jsxs(
3872
4010
  "form",
3873
4011
  {
@@ -3883,7 +4021,9 @@ function SignMessage({
3883
4021
  label: "Signature",
3884
4022
  error,
3885
4023
  hint: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3886
- "From your wallet\u2019s \u201Csign message\u201D (BIP-322), signed by",
4024
+ "From your wallet\u2019s \u201Csign message\u201D (",
4025
+ scheme === "legacy" ? "legacy, BIP-137" : "BIP-322",
4026
+ "), signed by",
3887
4027
  " ",
3888
4028
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-all font-mono", children: address }),
3889
4029
  "."
@@ -3951,6 +4091,7 @@ function SearchDialog({
3951
4091
  idle,
3952
4092
  defaultQuery = "",
3953
4093
  debounceMs = 120,
4094
+ browse = false,
3954
4095
  className
3955
4096
  }) {
3956
4097
  const [own, setOwn] = react.useState(false);
@@ -3987,7 +4128,7 @@ function SearchDialog({
3987
4128
  }, [hotkey]);
3988
4129
  react.useEffect(() => {
3989
4130
  const q = query.trim();
3990
- if (!q) {
4131
+ if (!q && !(browse && open)) {
3991
4132
  setGroups([]);
3992
4133
  setState("idle");
3993
4134
  return;
@@ -4009,14 +4150,15 @@ function SearchDialog({
4009
4150
  clearTimeout(t);
4010
4151
  ctl.abort();
4011
4152
  };
4012
- }, [query, debounceMs]);
4153
+ }, [query, debounceMs, browse, open]);
4013
4154
  react.useEffect(() => {
4014
4155
  listRef.current?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
4015
4156
  }, [active]);
4016
4157
  const choose = (r) => {
4017
4158
  setOpen(false);
4018
- if (onSelect) onSelect(r);
4019
- else window.location.assign(r.href);
4159
+ if (r.run) r.run();
4160
+ else if (onSelect) onSelect(r);
4161
+ else if (r.href) window.location.assign(r.href);
4020
4162
  };
4021
4163
  const optionId = (i) => `${listId}-o${i}`;
4022
4164
  const showList = state === "done" && flat.length > 0;
@@ -4087,25 +4229,28 @@ function SearchDialog({
4087
4229
  index++;
4088
4230
  const i = index;
4089
4231
  const on = i === active;
4232
+ const Option = r.href ? "a" : "div";
4090
4233
  return /* @__PURE__ */ jsxRuntime.jsxs(
4091
- "a",
4234
+ Option,
4092
4235
  {
4093
4236
  id: optionId(i),
4094
- href: r.href,
4237
+ ...r.href ? { href: r.href } : {},
4095
4238
  role: "option",
4096
4239
  "aria-selected": on,
4097
4240
  tabIndex: -1,
4098
4241
  onMouseMove: () => setActive(i),
4099
4242
  onClick: (e) => {
4100
- if (e.metaKey || e.ctrlKey || e.shiftKey) return;
4243
+ if (r.href && (e.metaKey || e.ctrlKey || e.shiftKey)) return;
4101
4244
  e.preventDefault();
4102
4245
  choose(r);
4103
4246
  },
4104
4247
  className: cn(
4105
4248
  "flex items-start gap-3 rounded-xl px-3 py-2.5 transition-colors",
4106
- on ? "bg-accent" : "hover:bg-accent"
4249
+ on ? "bg-accent" : "hover:bg-accent",
4250
+ !r.href && "cursor-pointer"
4107
4251
  ),
4108
4252
  children: [
4253
+ r.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "mt-0.5 flex size-5 shrink-0 items-center justify-center text-muted-foreground [&_svg]:size-[1.0625rem]", children: r.icon }) : null,
4109
4254
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
4110
4255
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.9375rem] font-medium text-foreground", children: r.title }),
4111
4256
  r.section ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.8125rem] text-muted-foreground", children: r.section }) : null,
@@ -4117,6 +4262,7 @@ function SearchDialog({
4117
4262
  }
4118
4263
  ) : r.excerpt ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-2 text-[0.875rem] leading-snug text-muted-foreground", children: r.excerpt }) : null
4119
4264
  ] }),
4265
+ r.meta ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 shrink-0 text-[0.8125rem] text-muted-foreground", children: r.meta }) : null,
4120
4266
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownLeft, { "aria-hidden": true, className: cn("mt-1 size-4 shrink-0 text-muted-foreground", !on && "invisible") })
4121
4267
  ]
4122
4268
  },
@@ -4125,11 +4271,11 @@ function SearchDialog({
4125
4271
  })
4126
4272
  ] }, gi)) }),
4127
4273
  state === "idle" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: idle ?? "Type a word: a protocol, a function, an error." }) : null,
4128
- state === "done" && flat.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: [
4274
+ state === "done" && flat.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: query.trim() ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4129
4275
  "No results for \u201C",
4130
4276
  query.trim(),
4131
4277
  "\u201D."
4132
- ] }) : null,
4278
+ ] }) : "Nothing here yet." }) : null,
4133
4279
  state === "error" ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: "Search is not available right now. Try again in a moment." }) : null
4134
4280
  ] }),
4135
4281
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-hidden": true, className: "hidden shrink-0 items-center gap-4 border-t border-border px-5 py-2.5 text-[0.75rem] text-muted-foreground sm:flex", children: [
@@ -4154,6 +4300,13 @@ function SearchDialog({
4154
4300
  ] }) })
4155
4301
  ] });
4156
4302
  }
4303
+ function CommandDialog({
4304
+ label = "Commands",
4305
+ placeholder = "Search, or run a command",
4306
+ ...props
4307
+ }) {
4308
+ return /* @__PURE__ */ jsxRuntime.jsx(SearchDialog, { ...props, label, placeholder, button: false, browse: true });
4309
+ }
4157
4310
  function pretty(content) {
4158
4311
  try {
4159
4312
  return JSON.stringify(JSON.parse(content), null, 2);
@@ -4395,7 +4548,7 @@ function FormSection({
4395
4548
  "aria-current": status === "current" ? "step" : void 0,
4396
4549
  className: cn("scroll-mt-24 rounded-[1.25rem] border border-border bg-card", className),
4397
4550
  children: [
4398
- /* @__PURE__ */ jsxRuntime.jsxs("header", { className: cn("flex items-start gap-3.5", tight ? "px-5 pt-5" : "px-6 pt-6"), children: [
4551
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: cn("flex flex-wrap items-start gap-x-3.5 gap-y-3", tight ? "px-5 pt-5" : "px-6 pt-6"), children: [
4399
4552
  n !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
4400
4553
  "span",
4401
4554
  {
@@ -4422,7 +4575,7 @@ function FormSection({
4422
4575
  ] }),
4423
4576
  hint ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: hint }) : null
4424
4577
  ] }),
4425
- action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: action }) : null
4578
+ action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("shrink-0 max-sm:basis-full", n !== void 0 && "max-sm:pl-[2.625rem]"), children: action }) : null
4426
4579
  ] }),
4427
4580
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col", tight ? "gap-4 p-5" : "gap-5 p-6", n !== void 0 && (tight ? "sm:pl-[3.875rem]" : "sm:pl-[4.125rem]")), children })
4428
4581
  ]
@@ -4582,6 +4735,13 @@ function BlockCountdown({
4582
4735
  ] }) : null
4583
4736
  ] });
4584
4737
  }
4738
+ var METER_FILL = {
4739
+ ink: "bg-foreground",
4740
+ brand: "bg-oca-orange-deep",
4741
+ good: "bg-success",
4742
+ caution: "bg-warning",
4743
+ bad: "bg-destructive"
4744
+ };
4585
4745
  function Meter({
4586
4746
  value,
4587
4747
  max,
@@ -4616,7 +4776,7 @@ function Meter({
4616
4776
  /* @__PURE__ */ jsxRuntime.jsx(
4617
4777
  "div",
4618
4778
  {
4619
- className: cn("h-full shrink-0 rounded-full", tone === "brand" ? "bg-oca-orange-deep" : "bg-foreground"),
4779
+ className: cn("h-full shrink-0 rounded-full", METER_FILL[tone]),
4620
4780
  style: { width: `${v * 100}%` }
4621
4781
  }
4622
4782
  ),
@@ -4652,27 +4812,30 @@ function FilterChips({
4652
4812
  onChange(cur.includes(v) ? cur.filter((x) => x !== v) : [...cur, v]);
4653
4813
  } else onChange(v);
4654
4814
  };
4655
- return /* @__PURE__ */ jsxRuntime.jsx(ScrollFade, { fade: "var(--background)", className: cn("w-full", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { role: "group", "aria-label": label, className: "flex w-max items-center gap-2 py-0.5", children: options.map((o) => {
4656
- const on = isOn(o.value);
4657
- return /* @__PURE__ */ jsxRuntime.jsxs(
4658
- "button",
4659
- {
4660
- type: "button",
4661
- "aria-pressed": on,
4662
- onClick: () => press(o.value),
4663
- className: cn(
4664
- "inline-flex shrink-0 items-center gap-1.5 rounded-full border px-3.5 text-[0.875rem] transition-colors",
4665
- tight ? "h-8" : "h-9",
4666
- on ? "border-foreground bg-foreground text-background" : "border-border bg-card text-muted-foreground hover:border-oca-hairline-strong hover:text-foreground"
4667
- ),
4668
- children: [
4669
- o.label,
4670
- o.count !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular", children: o.count.toLocaleString("en-US") }) : null
4671
- ]
4672
- },
4673
- o.value
4674
- );
4675
- }) }) });
4815
+ return (
4816
+ // Wraps rather than scrolls: every filter stays in view on a phone.
4817
+ /* @__PURE__ */ jsxRuntime.jsx("div", { role: "group", "aria-label": label, className: cn("flex flex-wrap items-center gap-2 py-0.5", className), children: options.map((o) => {
4818
+ const on = isOn(o.value);
4819
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4820
+ "button",
4821
+ {
4822
+ type: "button",
4823
+ "aria-pressed": on,
4824
+ onClick: () => press(o.value),
4825
+ className: cn(
4826
+ "inline-flex shrink-0 items-center gap-1.5 rounded-full border px-3.5 text-[0.875rem] transition-colors",
4827
+ tight ? "h-8" : "h-9",
4828
+ on ? "border-foreground bg-foreground text-background" : "border-border bg-card text-muted-foreground hover:border-oca-hairline-strong hover:text-foreground"
4829
+ ),
4830
+ children: [
4831
+ o.label,
4832
+ o.count !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-tabular", children: o.count.toLocaleString("en-US") }) : null
4833
+ ]
4834
+ },
4835
+ o.value
4836
+ );
4837
+ }) })
4838
+ );
4676
4839
  }
4677
4840
  function ToolGrid({
4678
4841
  tools,
@@ -4743,9 +4906,11 @@ exports.CardGrid = CardGrid;
4743
4906
  exports.Closing = Closing;
4744
4907
  exports.CodeBlock = CodeBlock;
4745
4908
  exports.CodeTabs = CodeTabs;
4909
+ exports.CommandDialog = CommandDialog;
4746
4910
  exports.ComparisonTable = ComparisonTable;
4747
4911
  exports.Container = Container;
4748
4912
  exports.CopyButton = CopyButton;
4913
+ exports.CountdownRing = CountdownRing;
4749
4914
  exports.DataTable = DataTable;
4750
4915
  exports.Diagram = Diagram;
4751
4916
  exports.Display = Display;
@@ -4774,6 +4939,7 @@ exports.Lead = Lead;
4774
4939
  exports.LegalDocument = LegalDocument;
4775
4940
  exports.LinkCard = LinkCard;
4776
4941
  exports.LoadingBlock = LoadingBlock;
4942
+ exports.LockedPreview = LockedPreview;
4777
4943
  exports.MdxTable = MdxTable;
4778
4944
  exports.Meter = Meter;
4779
4945
  exports.Monogram = Monogram;
@@ -4783,6 +4949,7 @@ exports.PackageCard = PackageCard;
4783
4949
  exports.PageHeader = PageHeader;
4784
4950
  exports.PageHero = PageHero;
4785
4951
  exports.PhoneFrame = PhoneFrame;
4952
+ exports.PlanCard = PlanCard;
4786
4953
  exports.ProgressSteps = ProgressSteps;
4787
4954
  exports.ProofStrip = ProofStrip;
4788
4955
  exports.Prose = Prose;