@orangecheck/app-design 1.2.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/chrome.d.mts +8 -3
  2. package/dist/chrome.d.ts +8 -3
  3. package/dist/chrome.js +605 -553
  4. package/dist/chrome.js.map +1 -1
  5. package/dist/chrome.mjs +605 -555
  6. package/dist/chrome.mjs.map +1 -1
  7. package/dist/code.js +3 -1
  8. package/dist/code.js.map +1 -1
  9. package/dist/code.mjs +3 -1
  10. package/dist/code.mjs.map +1 -1
  11. package/dist/components.d.mts +3 -3
  12. package/dist/components.d.ts +3 -3
  13. package/dist/components.js +730 -666
  14. package/dist/components.js.map +1 -1
  15. package/dist/components.mjs +731 -667
  16. package/dist/components.mjs.map +1 -1
  17. package/dist/{docs-Dxg4Tp_q.d.ts → docs-BB9gK4KF.d.ts} +18 -4
  18. package/dist/{docs-wJBfLS08.d.mts → docs-D-T-nHiu.d.mts} +18 -4
  19. package/dist/index.d.mts +4 -4
  20. package/dist/index.d.ts +4 -4
  21. package/dist/index.js +1549 -1406
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +1548 -1407
  24. package/dist/index.mjs.map +1 -1
  25. package/dist/mdx.d.mts +6 -2
  26. package/dist/mdx.d.ts +6 -2
  27. package/dist/mdx.js +168 -74
  28. package/dist/mdx.js.map +1 -1
  29. package/dist/mdx.mjs +169 -75
  30. package/dist/mdx.mjs.map +1 -1
  31. package/dist/primitives.d.mts +9 -3
  32. package/dist/primitives.d.ts +9 -3
  33. package/dist/primitives.js +7 -6
  34. package/dist/primitives.js.map +1 -1
  35. package/dist/primitives.mjs +7 -6
  36. package/dist/primitives.mjs.map +1 -1
  37. package/dist/session.d.mts +4 -3
  38. package/dist/session.d.ts +4 -3
  39. package/dist/session.js +27 -3
  40. package/dist/session.js.map +1 -1
  41. package/dist/session.mjs +27 -3
  42. package/dist/session.mjs.map +1 -1
  43. package/dist/styles/swagger.css +252 -0
  44. package/dist/styles/tokens.css +2 -0
  45. package/dist/{tool-shell-kqGWMTep.d.mts → tool-shell-D8Q8XX11.d.mts} +8 -5
  46. package/dist/{tool-shell-DLSwUxTD.d.ts → tool-shell-gmlj47Ie.d.ts} +8 -5
  47. package/package.json +1 -1
@@ -4,11 +4,12 @@ import { extendTailwindMerge } from 'tailwind-merge';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { cva } from 'class-variance-authority';
6
6
  import * as TabsPrimitive from '@radix-ui/react-tabs';
7
- import { ChevronDown, Check, Search, Copy, ArrowUpRight, ArrowRight, ChevronRight, CornerDownLeft, Download, FileText, Upload, ArrowLeft, Lock, CircleDashed, CircleMinus, Clock, CircleX, CircleCheck } from 'lucide-react';
7
+ import { ChevronDown, Check, Search, Copy, ArrowUpRight, ArrowRight, ChevronRight, CornerDownLeft, Download, FileText, Upload, ArrowLeft, Lock, CircleDashed, CircleMinus, CircleSlash, Clock, CircleX, CircleCheck } from 'lucide-react';
8
8
  import { Slot } from '@radix-ui/react-slot';
9
9
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
10
10
  import 'sonner';
11
11
  import Link from 'next/link';
12
+ import { useRouter } from 'next/compat/router';
12
13
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
13
14
  import * as LabelPrimitive from '@radix-ui/react-label';
14
15
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
@@ -1675,11 +1676,13 @@ function forClipboard(text, lang) {
1675
1676
  if (!lines.some((l) => l.startsWith("$ "))) return text;
1676
1677
  return lines.filter((l) => l.startsWith("$ ")).map((l) => l.slice(2)).join("\n");
1677
1678
  }
1678
- function linesFromDom(pre) {
1679
+ function linesFromDom(pre, newline) {
1679
1680
  if (!pre) return null;
1680
1681
  const lines = pre.querySelectorAll("[data-line]");
1681
1682
  if (lines.length === 0) return pre.textContent ?? "";
1682
- return Array.from(lines).filter((l) => l.getAttribute("data-diff") !== "remove").map((l) => l.textContent ?? "").join("\n");
1683
+ const text = Array.from(lines).filter((l) => l.getAttribute("data-diff") !== "remove").map((l) => l.textContent ?? "").join("\n");
1684
+ return newline ? `${text}
1685
+ ` : text;
1683
1686
  }
1684
1687
  function prepare(code, lang, marks, diff) {
1685
1688
  const d = diff ? readDiff(code) : null;
@@ -1688,7 +1691,8 @@ function prepare(code, lang, marks, diff) {
1688
1691
  const kept = d ? src.split("\n").filter((_, i) => d.diff.get(i + 1) !== "remove") : null;
1689
1692
  return {
1690
1693
  html: linesToHtml(lines, { highlight: parseLineRanges(marks), diff: d?.diff }),
1691
- copy: kept ? kept.join("\n") : src,
1694
+ // Byte for byte, the final newline too: a hash printed beside the code must match a copy of it.
1695
+ copy: kept ? kept.join("\n") + (/\n$/.test(code) ? "\n" : "") : code,
1692
1696
  lines: lines.length,
1693
1697
  diff: !!d
1694
1698
  };
@@ -1753,6 +1757,7 @@ function CodeBlock({
1753
1757
  code,
1754
1758
  html,
1755
1759
  children,
1760
+ trailingNewline = false,
1756
1761
  lang,
1757
1762
  caption,
1758
1763
  copy = true,
@@ -1773,7 +1778,7 @@ function CodeBlock({
1773
1778
  );
1774
1779
  const markup = prepared?.html ?? html;
1775
1780
  const lines = prepared?.lines ?? (html !== void 0 ? html.split("\n").length : code?.split("\n").length ?? 0);
1776
- const read = () => forClipboard(prepared?.copy ?? linesFromDom(preRef.current) ?? code ?? "", lang);
1781
+ const read = () => forClipboard(prepared?.copy ?? linesFromDom(preRef.current, trailingNewline) ?? code ?? "", lang);
1777
1782
  return /* @__PURE__ */ jsxs("figure", { className: cn(FRAME, className), children: [
1778
1783
  /* @__PURE__ */ jsxs("figcaption", { className: "flex h-11 items-center justify-between gap-3 border-b border-[var(--oca-code-line)] pl-5 pr-2", children: [
1779
1784
  /* @__PURE__ */ jsx("span", { className: "truncate text-[0.8125rem] text-oca-ink-subtle", children: caption ?? languageName(lang) ?? "Code" }),
@@ -2552,12 +2557,21 @@ function Faq({
2552
2557
  return /* @__PURE__ */ jsx(Accordion, { single: true, className, children: items.map((it, i) => /* @__PURE__ */ jsx(AccordionItem, { id: it.id, title: it.q, children: it.a }, it.id ?? i)) });
2553
2558
  }
2554
2559
  var LINK = "text-foreground underline decoration-foreground/35 underline-offset-4 transition-colors hover:decoration-foreground";
2560
+ var SCHEME = /^[a-z][a-z\d+.-]*:/i;
2561
+ function useResolved(href) {
2562
+ const router = useRouter();
2563
+ if (!router || !href || href.startsWith("/") || href.startsWith("#") || href.startsWith("?") || SCHEME.test(href)) return href;
2564
+ const here = router.asPath.split(/[?#]/)[0] || "/";
2565
+ const url = new URL(href, `https://page.invalid${here}`);
2566
+ return url.pathname + url.search + url.hash;
2567
+ }
2555
2568
  function TextLink({
2556
- href,
2569
+ href: written,
2557
2570
  children,
2558
2571
  external,
2559
2572
  className
2560
2573
  }) {
2574
+ const href = useResolved(written);
2561
2575
  const internal = href.startsWith("/") && !href.startsWith("/api/") && !href.startsWith("/.well-known/");
2562
2576
  const offsite = external ?? /^https?:\/\//.test(href);
2563
2577
  if (internal && !offsite) {
@@ -2793,6 +2807,10 @@ function protocolSite(slug) {
2793
2807
  { href: `${OCHK_IO}/trust`, label: "Trust" },
2794
2808
  { href: `${OCHK_IO}/about`, label: "About" }
2795
2809
  ];
2810
+ var InDocsContext = sharedContext("in-docs", false);
2811
+ function useInDocs() {
2812
+ return useContext(InDocsContext);
2813
+ }
2796
2814
  var WORD = {
2797
2815
  live: "Live",
2798
2816
  testing: "In testing",
@@ -2822,6 +2840,7 @@ function ProtocolGrid({
2822
2840
  link = "page",
2823
2841
  className
2824
2842
  }) {
2843
+ const inDocs = useInDocs();
2825
2844
  return /* @__PURE__ */ 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) => {
2826
2845
  const p = protocolSite(slug);
2827
2846
  const i = PROTOCOL_ORDER.indexOf(slug);
@@ -2834,7 +2853,7 @@ function ProtocolGrid({
2834
2853
  ] }),
2835
2854
  p.status !== "live" ? /* @__PURE__ */ jsx(StatusBadge, { status: p.status }) : null
2836
2855
  ] }),
2837
- /* @__PURE__ */ jsx("h3", { className: "oca-display-3", children: /* @__PURE__ */ jsx(
2856
+ /* @__PURE__ */ jsx("h3", { className: "oca-display-3", children: link === "docs" && inDocs ? /* @__PURE__ */ jsx(Link, { href: `/${p.slug}`, className: STRETCH, children: p.label }) : /* @__PURE__ */ jsx(
2838
2857
  "a",
2839
2858
  {
2840
2859
  href: link === "tool" ? p.toolHref : link === "docs" ? `${DOCS_HREF}/${p.slug}` : p.pageHref,
@@ -2941,16 +2960,17 @@ var Label = forwardRef(function Label2({ className, ...props }, ref) {
2941
2960
  }
2942
2961
  );
2943
2962
  });
2944
- function Field({ label, hint, optional, error, children, className, hideLabel, action }) {
2945
- const id = useId();
2963
+ function Field({ label, hint, optional, error, children, id: fixedId, className, hideLabel, action }) {
2964
+ const generated = useId();
2965
+ const id = fixedId ?? generated;
2946
2966
  const hintId = hint ? `${id}-hint` : void 0;
2947
2967
  const errorId = error ? `${id}-error` : void 0;
2948
- const describedBy = [hintId, errorId].filter(Boolean).join(" ") || void 0;
2949
- const control = isValidElement(children) ? cloneElement(children, {
2968
+ const wiring = {
2950
2969
  id,
2951
- "aria-describedby": describedBy,
2970
+ "aria-describedby": [hintId, errorId].filter(Boolean).join(" ") || void 0,
2952
2971
  "aria-invalid": error ? true : void 0
2953
- }) : children;
2972
+ };
2973
+ const control = typeof children === "function" ? children(wiring) : isValidElement(children) ? cloneElement(children, { ...wiring }) : children;
2954
2974
  const hintNode = hint ? /* @__PURE__ */ jsx("p", { id: hintId, className: "text-[0.8125rem] leading-snug text-muted-foreground", children: hint }) : null;
2955
2975
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
2956
2976
  /* @__PURE__ */ jsxs(Label, { htmlFor: id, className: hideLabel ? "sr-only" : "flex items-baseline gap-2", children: [
@@ -3081,736 +3101,780 @@ forwardRef(function RadioGroupItem2({ className, ...props }, ref) {
3081
3101
  }
3082
3102
  );
3083
3103
  });
3084
- function ProtocolHero({
3085
- protocol: protocol2,
3104
+ var isInternal = (href) => href.startsWith("/") || href.startsWith("#");
3105
+ function DocLink({ href, className, children, ...rest }) {
3106
+ return isInternal(href) ? /* @__PURE__ */ jsx(Link, { href, className, ...rest, children }) : /* @__PURE__ */ jsx("a", { href, className, ...rest, children });
3107
+ }
3108
+ function Breadcrumbs({ items, action, className }) {
3109
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex min-h-11 items-center justify-between gap-4 sm:min-h-0", className), children: [
3110
+ /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "min-w-0", children: /* @__PURE__ */ jsx("ol", { className: "flex min-w-0 items-center gap-1.5 text-[0.875rem] text-muted-foreground", children: items.map((c, i) => {
3111
+ const last = i === items.length - 1;
3112
+ return /* @__PURE__ */ jsxs("li", { className: cn("flex items-center gap-1.5", last ? "min-w-0" : "shrink-0"), children: [
3113
+ c.href && !last ? /* @__PURE__ */ jsx(DocLink, { href: c.href, className: "inline-flex min-h-11 items-center transition-colors hover:text-foreground sm:min-h-0", children: c.label }) : /* @__PURE__ */ jsx("span", { "aria-current": last ? "page" : void 0, className: cn("truncate", last && "text-foreground"), children: c.label }),
3114
+ !last ? /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-oca-subtle" }) : null
3115
+ ] }, i);
3116
+ }) }) }),
3117
+ action ? /* @__PURE__ */ jsx("div", { className: "shrink-0 text-[0.875rem]", children: action }) : null
3118
+ ] });
3119
+ }
3120
+ function DocsPager({ prev, next, className }) {
3121
+ if (!prev && !next) return null;
3122
+ const card = (l, dir) => /* @__PURE__ */ jsxs(
3123
+ DocLink,
3124
+ {
3125
+ href: l.href,
3126
+ className: cn(
3127
+ "group flex min-h-20 flex-col justify-center gap-1 rounded-2xl border border-border bg-card px-5 py-4 transition-colors hover:border-oca-hairline-strong",
3128
+ dir === "next" && "items-end text-right sm:col-start-2"
3129
+ ),
3130
+ children: [
3131
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-[0.8125rem] text-muted-foreground", children: [
3132
+ dir === "prev" ? /* @__PURE__ */ jsx(ArrowLeft, { "aria-hidden": true, className: "size-3.5" }) : null,
3133
+ dir === "prev" ? "Previous" : "Next",
3134
+ l.section ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\xB7" }) : null,
3135
+ l.section ? /* @__PURE__ */ jsx("span", { className: "truncate", children: l.section }) : null,
3136
+ dir === "next" ? /* @__PURE__ */ jsx(ArrowRight, { "aria-hidden": true, className: "size-3.5" }) : null
3137
+ ] }),
3138
+ /* @__PURE__ */ jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: l.label })
3139
+ ]
3140
+ }
3141
+ );
3142
+ return /* @__PURE__ */ jsxs("nav", { "aria-label": "Previous and next page", className: cn("grid grid-cols-1 gap-3 border-t border-border pt-8 sm:grid-cols-2", className), children: [
3143
+ prev ? card(prev, "prev") : null,
3144
+ next ? card(next, "next") : null
3145
+ ] });
3146
+ }
3147
+ function useHeadings(selector = "#docs-content", key) {
3148
+ const [items, setItems] = useState([]);
3149
+ useEffect(() => {
3150
+ const read = () => {
3151
+ const root = document.querySelector(selector);
3152
+ if (!root) return setItems([]);
3153
+ setItems(
3154
+ Array.from(root.querySelectorAll("h2[id], h3[id]")).map((h) => ({
3155
+ id: h.id,
3156
+ // The anchor link's "#" is not part of the name.
3157
+ label: (h.querySelector("[data-heading-text]") ?? h).textContent?.trim() ?? "",
3158
+ level: h.tagName === "H3" ? 3 : 2
3159
+ }))
3160
+ );
3161
+ };
3162
+ const raf = requestAnimationFrame(read);
3163
+ const t = setTimeout(read, 80);
3164
+ return () => {
3165
+ cancelAnimationFrame(raf);
3166
+ clearTimeout(t);
3167
+ };
3168
+ }, [selector, key]);
3169
+ const activeId = useActiveHeading(items.map((i) => i.id));
3170
+ return { items, activeId };
3171
+ }
3172
+ function OnThisPage({
3173
+ items,
3174
+ activeId,
3175
+ title = "On this page",
3176
+ onNavigate,
3177
+ className
3178
+ }) {
3179
+ const id = useId();
3180
+ if (items.length === 0) return null;
3181
+ return (
3182
+ // With no visible title (a folded list under its own summary) the name is still "On this page".
3183
+ /* @__PURE__ */ jsxs("nav", { "aria-labelledby": title ? id : void 0, "aria-label": title ? void 0 : "On this page", className, children: [
3184
+ title ? /* @__PURE__ */ jsx("p", { id, className: "mb-3 text-[0.875rem] font-medium", children: title }) : null,
3185
+ /* @__PURE__ */ jsx("ul", { children: items.map((t) => {
3186
+ const on = t.id === activeId;
3187
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
3188
+ "a",
3189
+ {
3190
+ href: `#${t.id}`,
3191
+ onClick: onNavigate,
3192
+ "aria-current": on ? "location" : void 0,
3193
+ className: cn(
3194
+ "block border-l py-1.5 text-[0.875rem] leading-snug transition-colors",
3195
+ t.level === 3 ? "pl-7" : "pl-4",
3196
+ on ? "border-foreground text-foreground" : "border-border text-muted-foreground hover:text-foreground"
3197
+ ),
3198
+ children: t.label
3199
+ }
3200
+ ) }, t.id);
3201
+ }) })
3202
+ ] })
3203
+ );
3204
+ }
3205
+ var CALLOUT_TONE = { note: "neutral", warning: "brand", danger: "danger" };
3206
+ function Callout({
3207
+ tone = "note",
3086
3208
  title,
3087
- lead,
3088
- actions,
3089
- art,
3090
3209
  children,
3091
3210
  className
3092
3211
  }) {
3093
- const p = protocolSite(protocol2);
3094
3212
  return /* @__PURE__ */ jsx(
3095
- PageHero,
3213
+ Notice,
3096
3214
  {
3097
- className,
3098
- eyebrow: `Protocol \xB7 ${p.verb}`,
3215
+ tone: CALLOUT_TONE[tone],
3099
3216
  title,
3100
- lead,
3101
- actions,
3102
- art,
3103
- children: p.status !== "live" || children ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-4", children: [
3104
- p.status !== "live" ? /* @__PURE__ */ jsx(StatusBadge, { status: p.status }) : null,
3105
- children
3106
- ] }) : null
3217
+ role: "note",
3218
+ className: cn("my-6 [&_p]:my-0 [&_p]:text-[0.9375rem] [&_p]:leading-relaxed [&_p+p]:mt-3", className),
3219
+ children
3107
3220
  }
3108
3221
  );
3109
3222
  }
3110
- function ProtocolNav({
3111
- current,
3112
- link = "page",
3113
- className
3114
- }) {
3115
- return /* @__PURE__ */ jsx("nav", { "aria-label": "Protocols", className, children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--background)", children: /* @__PURE__ */ jsx("ul", { className: "flex w-max min-w-full items-center gap-6 border-b border-border", children: PROTOCOLS.map((p) => {
3116
- const on = p.slug === current;
3117
- return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
3118
- "a",
3119
- {
3120
- href: link === "tool" ? p.toolHref : p.pageHref,
3121
- "aria-current": on ? "page" : void 0,
3122
- className: cn(
3123
- "-mb-px inline-flex h-11 items-center border-b-2 text-[0.9375rem] transition-colors",
3124
- on ? "border-foreground text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
3125
- ),
3126
- children: p.label
3127
- }
3128
- ) }, p.slug);
3129
- }) }) }) });
3130
- }
3131
- function SpecCard({
3132
- protocol: protocol2,
3133
- version,
3134
- license,
3135
- vectors,
3136
- size = "md",
3137
- className
3138
- }) {
3139
- const p = protocolSite(protocol2);
3140
- const repo = `oc-${p.slug}-protocol`;
3141
- const facts = [
3142
- ["Version", version],
3143
- ...license ? [["Licence", license]] : [],
3144
- ["Nostr kind", p.kinds],
3145
- ...vectors !== void 0 ? [["Test vectors", String(vectors)]] : []
3146
- ];
3147
- if (size === "sm") {
3148
- return /* @__PURE__ */ jsxs(
3149
- "a",
3223
+ function Step({ title, id, children }) {
3224
+ return /* @__PURE__ */ jsxs("li", { className: "relative pb-8 pl-11 last:pb-0 [counter-increment:oca-step]", children: [
3225
+ /* @__PURE__ */ jsx(
3226
+ "span",
3150
3227
  {
3151
- href: p.specHref,
3152
- className: cn(
3153
- "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",
3154
- className
3155
- ),
3156
- children: [
3157
- /* @__PURE__ */ jsx("span", { className: "font-mono text-[0.8125rem] text-foreground", children: repo }),
3158
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: facts.map(([k, v]) => k === "Version" ? `v${v}` : k === "Nostr kind" ? `kind ${v}` : v).join(" \xB7 ") }),
3159
- /* @__PURE__ */ jsxs("span", { className: "ml-auto flex items-center gap-1 text-muted-foreground group-hover:text-foreground", children: [
3160
- "Read the spec ",
3161
- /* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": true, className: "size-4" })
3162
- ] })
3163
- ]
3228
+ "aria-hidden": true,
3229
+ className: "absolute left-0 top-0 flex size-7 items-center justify-center rounded-full border border-oca-hairline-strong bg-card text-[0.8125rem] oca-tabular text-foreground before:content-[counter(oca-step)]"
3164
3230
  }
3165
- );
3166
- }
3167
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-6 rounded-[1.25rem] border border-border bg-card p-6 md:p-8", className), children: [
3168
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
3169
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
3170
- /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] text-muted-foreground", children: "The spec" }),
3171
- /* @__PURE__ */ jsx("h3", { className: "oca-title break-all font-mono text-[1.0625rem] tracking-normal", children: repo })
3172
- ] }),
3173
- p.status !== "live" ? /* @__PURE__ */ jsx(StatusBadge, { status: p.status }) : null
3174
- ] }),
3175
- /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-4", children: facts.map(([k, v]) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
3176
- /* @__PURE__ */ jsx("dt", { className: "text-[0.8125rem] text-muted-foreground", children: k }),
3177
- /* @__PURE__ */ jsx("dd", { className: "oca-tabular text-[1.0625rem]", children: v })
3178
- ] }, k)) }),
3179
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { asChild: true, variant: "secondary", size: "sm", children: /* @__PURE__ */ jsxs("a", { href: p.specHref, children: [
3180
- "Read the spec ",
3181
- /* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": true })
3182
- ] }) }) })
3231
+ ),
3232
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "absolute bottom-1 left-[0.8125rem] top-9 w-px bg-border" }),
3233
+ /* @__PURE__ */ jsx("h3", { id, className: "scroll-mt-28 pt-0.5 text-[1.0625rem] font-medium leading-snug tracking-[-0.008em] text-foreground", children: title }),
3234
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-muted-foreground [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children })
3183
3235
  ] });
3184
3236
  }
3185
- function VerifyBox({
3186
- action,
3187
- param = "q",
3237
+ function Steps({ children, className }) {
3238
+ return /* @__PURE__ */ jsx("ol", { className: cn("not-prose my-8 flex flex-col [counter-reset:oca-step] [&>li:last-child>span:nth-child(2)]:hidden", className), children });
3239
+ }
3240
+ function LinkCard({
3241
+ href,
3188
3242
  title,
3189
3243
  description,
3190
- label = "Id, envelope or link",
3191
- placeholder,
3192
- hint,
3193
- submitLabel = "Verify",
3194
- multiline = false,
3195
- onVerify,
3244
+ icon,
3245
+ meta,
3196
3246
  className
3197
3247
  }) {
3198
- const [value, setValue] = useState("");
3199
- const submit = (e) => {
3200
- if (!onVerify) return;
3201
- e.preventDefault();
3202
- if (value.trim()) onVerify(value.trim());
3203
- };
3204
- const button = /* @__PURE__ */ jsx(Button, { type: "submit", className: multiline ? void 0 : "w-full sm:w-auto", children: submitLabel });
3248
+ const Arrow = isInternal(href) ? ArrowRight : ArrowUpRight;
3205
3249
  return /* @__PURE__ */ jsxs(
3206
- "form",
3250
+ DocLink,
3207
3251
  {
3208
- action,
3209
- method: "get",
3210
- onSubmit: submit,
3211
- className: cn("flex flex-col gap-5 rounded-[1.25rem] border border-border bg-card p-6 md:p-8", className),
3252
+ href,
3253
+ className: cn(
3254
+ "group flex h-full flex-col gap-3 rounded-[1.25rem] border border-border bg-card p-5 transition-colors hover:border-oca-hairline-strong",
3255
+ className
3256
+ ),
3212
3257
  children: [
3213
- title || description ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
3214
- title ? /* @__PURE__ */ jsx("h3", { className: "oca-title", children: title }) : null,
3215
- description ? /* @__PURE__ */ jsx("p", { className: "oca-body text-[0.9375rem]", children: description }) : null
3216
- ] }) : null,
3217
- multiline ? /* @__PURE__ */ jsxs(Fragment, { children: [
3218
- /* @__PURE__ */ jsx(Field, { label, hint, children: /* @__PURE__ */ jsx(
3219
- Textarea,
3220
- {
3221
- name: param,
3222
- required: true,
3223
- value,
3224
- onChange: (e) => setValue(e.target.value),
3225
- placeholder,
3226
- spellCheck: false,
3227
- className: "min-h-32 font-mono text-base md:text-[0.8125rem]"
3228
- }
3229
- ) }),
3230
- /* @__PURE__ */ jsx("div", { children: button })
3231
- ] }) : /* @__PURE__ */ jsx(Field, { label, hint, action: button, children: /* @__PURE__ */ jsx(
3232
- Input,
3233
- {
3234
- name: param,
3235
- required: true,
3236
- value,
3237
- onChange: (e) => setValue(e.target.value),
3238
- placeholder,
3239
- spellCheck: false,
3240
- autoComplete: "off",
3241
- className: "font-mono text-base md:text-[0.875rem]"
3242
- }
3243
- ) })
3258
+ /* @__PURE__ */ jsxs("span", { className: "flex items-start justify-between gap-3", children: [
3259
+ icon ? /* @__PURE__ */ jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-xl bg-muted text-foreground [&_svg]:size-[1.125rem]", children: icon }) : /* @__PURE__ */ jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }),
3260
+ /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [
3261
+ meta,
3262
+ /* @__PURE__ */ jsx(Arrow, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-foreground" })
3263
+ ] })
3264
+ ] }),
3265
+ icon ? /* @__PURE__ */ jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }) : null,
3266
+ description ? /* @__PURE__ */ jsx("span", { className: "text-[0.9375rem] leading-relaxed text-muted-foreground", children: description }) : null
3244
3267
  ]
3245
3268
  }
3246
3269
  );
3247
3270
  }
3248
- var TINT = "bg-[color-mix(in_oklab,var(--oca-orange)_9%,var(--card))]";
3249
- function ComparisonTable({
3250
- columns,
3271
+ function CardGrid({ columns = 2, children, className }) {
3272
+ return /* @__PURE__ */ jsx("div", { className: cn("not-prose my-6 grid grid-cols-1 gap-3 sm:grid-cols-2", columns === 3 && "lg:grid-cols-3", className), children });
3273
+ }
3274
+ function MdxTable({ className, ...props }) {
3275
+ return /* @__PURE__ */ jsx("div", { className: "not-prose my-6 overflow-hidden rounded-2xl border border-border bg-card", children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsx(
3276
+ "table",
3277
+ {
3278
+ className: cn(
3279
+ "w-full border-collapse text-left text-[0.875rem] leading-relaxed",
3280
+ "[&_th]:whitespace-nowrap [&_th]:border-b [&_th]:border-oca-hairline-strong [&_th]:bg-oca-table-head [&_th]:px-4 [&_th]:py-2.5 [&_th]:text-[0.8125rem] [&_th]:font-medium [&_th]:text-foreground",
3281
+ "[&_td]:border-t [&_td]:border-border [&_td]:px-4 [&_td]:py-2.5 [&_td]:align-top [&_td]:text-muted-foreground [&_tbody_tr:first-child_td]:border-t-0",
3282
+ "[&_td_code]:bg-transparent [&_td_code]:p-0 [&_td_code]:text-foreground [&_td:first-child]:text-foreground",
3283
+ "[&_[align=center]]:text-center [&_[align=right]]:text-right",
3284
+ // On a phone a cell keeps a readable width; the table scrolls instead of crushing it.
3285
+ "max-sm:[&_td]:min-w-[9rem]",
3286
+ className
3287
+ ),
3288
+ ...props
3289
+ }
3290
+ ) }) });
3291
+ }
3292
+ var said = (n) => n !== void 0 && n !== null && n !== false && n !== "";
3293
+ function ApiTable({
3251
3294
  rows,
3252
- label,
3253
- propertyHeading = "Property",
3295
+ caption,
3296
+ nameHeader = "Name",
3254
3297
  className
3255
3298
  }) {
3256
- const wide = columns.length > 3;
3257
- const grid = wide ? "lg:grid lg:grid-cols-[var(--oca-compare)]" : "md:grid md:grid-cols-[var(--oca-compare)]";
3258
- const desk = wide ? "lg" : "md";
3259
- const style = {
3260
- // The argued-for column gets a little more room: its answers carry the page.
3261
- "--oca-compare": ["minmax(0, 1.4fr)", ...columns.map((c) => c.highlight ? "minmax(0, 1.3fr)" : "minmax(0, 1fr)")].join(" ")
3299
+ const hasDefault = rows.some((r) => r.default !== void 0);
3300
+ const hasDescription = rows.some((r) => said(r.description));
3301
+ const hasSource = rows.some((r) => said(r.source));
3302
+ const cell = "px-4 py-3 max-sm:p-0";
3303
+ return /* @__PURE__ */ jsx("div", { className: cn("not-prose my-6 overflow-hidden rounded-2xl border border-border bg-card", className), children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-left text-[0.875rem] max-sm:block", children: [
3304
+ caption ? /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }) : null,
3305
+ /* @__PURE__ */ jsx("thead", { className: "max-sm:sr-only", children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-oca-hairline-strong bg-oca-table-head text-[0.8125rem]", children: [
3306
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: nameHeader }),
3307
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Type" }),
3308
+ hasDefault ? /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Default" }) : null,
3309
+ hasDescription ? /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Description" }) : null,
3310
+ hasSource ? /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Defined in" }) : null
3311
+ ] }) }),
3312
+ /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-border max-sm:block", children: rows.map((r) => /* @__PURE__ */ jsxs(
3313
+ "tr",
3314
+ {
3315
+ id: r.id,
3316
+ className: "scroll-mt-28 align-top target:bg-muted max-sm:flex max-sm:flex-col max-sm:gap-1.5 max-sm:px-4 max-sm:py-3.5",
3317
+ children: [
3318
+ /* @__PURE__ */ jsx("th", { scope: "row", className: cn(cell, "text-left font-normal"), children: /* @__PURE__ */ jsxs("span", { className: "flex flex-col items-start gap-1 max-sm:flex-row max-sm:flex-wrap max-sm:items-baseline max-sm:gap-x-2", children: [
3319
+ /* @__PURE__ */ jsx("code", { className: cn("font-mono text-[0.8125rem] text-foreground max-sm:text-[0.875rem]", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
3320
+ r.required ? /* @__PURE__ */ jsx("span", { className: "text-[0.75rem] text-oca-accent-ink", children: "Required" }) : null,
3321
+ r.deprecated ? /* @__PURE__ */ jsx(Badge, { tone: "muted", children: "Deprecated" }) : null,
3322
+ r.status ? /* @__PURE__ */ jsx(StatusBadge, { status: r.status }) : null
3323
+ ] }) }),
3324
+ /* @__PURE__ */ jsx("td", { className: cn(cell, "font-mono text-[0.8125rem] text-muted-foreground max-sm:break-all", !said(r.type) && "max-sm:hidden"), children: r.type ?? "\u2014" }),
3325
+ hasDefault ? /* @__PURE__ */ jsxs("td", { className: cn(cell, "font-mono text-[0.8125rem] text-muted-foreground max-sm:order-last", r.default === void 0 && "max-sm:hidden"), children: [
3326
+ /* @__PURE__ */ jsx("span", { className: "font-sans sm:hidden", children: "Default " }),
3327
+ r.default ?? "\u2014"
3328
+ ] }) : null,
3329
+ hasDescription ? /* @__PURE__ */ jsx("td", { className: cn(cell, "leading-relaxed text-muted-foreground", !said(r.description) && "max-sm:hidden"), children: r.description }) : null,
3330
+ hasSource ? /* @__PURE__ */ jsx("td", { className: cn(cell, "text-[0.8125rem] text-muted-foreground max-sm:order-last max-sm:break-all", !said(r.source) && "max-sm:hidden"), children: r.source }) : null
3331
+ ]
3332
+ },
3333
+ r.id ?? r.name
3334
+ )) })
3335
+ ] }) }) });
3336
+ }
3337
+ function useDarkMode() {
3338
+ const [dark, setDark] = useState(false);
3339
+ useEffect(() => {
3340
+ const root = document.documentElement;
3341
+ const read = () => setDark(root.classList.contains("dark"));
3342
+ read();
3343
+ const mo = new MutationObserver(read);
3344
+ mo.observe(root, { attributes: true, attributeFilter: ["class"] });
3345
+ return () => mo.disconnect();
3346
+ }, []);
3347
+ return dark;
3348
+ }
3349
+ function mermaidTheme(el) {
3350
+ const css = getComputedStyle(el);
3351
+ const v = (name) => css.getPropertyValue(name).trim();
3352
+ const card = v("--card");
3353
+ const muted = v("--muted");
3354
+ const text = v("--foreground");
3355
+ const subtle = v("--muted-foreground");
3356
+ const line = v("--input");
3357
+ const hair = v("--oca-hairline-strong");
3358
+ return {
3359
+ background: "transparent",
3360
+ fontFamily: css.fontFamily,
3361
+ fontSize: "14px",
3362
+ textColor: text,
3363
+ mainBkg: card,
3364
+ primaryColor: card,
3365
+ primaryTextColor: text,
3366
+ primaryBorderColor: hair,
3367
+ secondaryColor: muted,
3368
+ secondaryTextColor: text,
3369
+ secondaryBorderColor: hair,
3370
+ tertiaryColor: muted,
3371
+ tertiaryTextColor: text,
3372
+ tertiaryBorderColor: hair,
3373
+ nodeBorder: hair,
3374
+ lineColor: line,
3375
+ edgeLabelBackground: card,
3376
+ clusterBkg: muted,
3377
+ clusterBorder: hair,
3378
+ titleColor: text,
3379
+ noteBkgColor: muted,
3380
+ noteTextColor: text,
3381
+ noteBorderColor: hair,
3382
+ actorBkg: card,
3383
+ actorBorder: hair,
3384
+ actorTextColor: text,
3385
+ actorLineColor: line,
3386
+ signalColor: text,
3387
+ signalTextColor: text,
3388
+ labelBoxBkgColor: card,
3389
+ labelBoxBorderColor: hair,
3390
+ labelTextColor: text,
3391
+ loopTextColor: subtle,
3392
+ activationBkgColor: muted,
3393
+ activationBorderColor: hair,
3394
+ sequenceNumberColor: card
3262
3395
  };
3263
- const ordered = [...columns].sort((a, b) => Number(Boolean(b.highlight)) - Number(Boolean(a.highlight)));
3264
- return /* @__PURE__ */ jsxs("ul", { "aria-label": label, style, className: cn("divide-y divide-border rounded-[1.25rem] border border-border bg-card", className), children: [
3265
- /* @__PURE__ */ jsxs(
3266
- "li",
3396
+ }
3397
+ var FIT = 4 / 3;
3398
+ function naturalSize(svg) {
3399
+ const w = svg.match(/viewBox="[\d.-]+ [\d.-]+ ([\d.]+) [\d.]+"/)?.[1];
3400
+ if (!w) return { svg, width: null };
3401
+ const width = Math.ceil(Number(w));
3402
+ return {
3403
+ svg: svg.replace(/<svg([^>]*?)\swidth="100%"/, `<svg$1 width="${width}"`).replace(/max-width:\s*[\d.]+px;?/, ""),
3404
+ width
3405
+ };
3406
+ }
3407
+ function useInnerWidth(ref, padding) {
3408
+ const [width, setWidth] = useState(null);
3409
+ useEffect(() => {
3410
+ const el = ref.current;
3411
+ if (!el) return;
3412
+ const ro = new ResizeObserver(() => setWidth(el.clientWidth - padding));
3413
+ ro.observe(el);
3414
+ return () => ro.disconnect();
3415
+ }, [ref, padding]);
3416
+ return width;
3417
+ }
3418
+ function Diagram({ chart, caption, load, className }) {
3419
+ const ref = useRef(null);
3420
+ const dark = useDarkMode();
3421
+ const raw = useId();
3422
+ const [drawn, setDrawn] = useState(null);
3423
+ const [failed, setFailed] = useState(false);
3424
+ const room = useInnerWidth(ref, 48);
3425
+ const fits = drawn?.width != null && room != null && drawn.width <= room * FIT;
3426
+ useEffect(() => {
3427
+ let live = true;
3428
+ const el = ref.current;
3429
+ if (!el) return;
3430
+ (async () => {
3431
+ try {
3432
+ const mod = await load();
3433
+ const mermaid = "default" in mod ? mod.default : mod;
3434
+ mermaid.initialize({ startOnLoad: false, securityLevel: "strict", theme: "base", themeVariables: mermaidTheme(el) });
3435
+ const { svg } = await mermaid.render(`oca-diagram-${raw.replace(/[^a-zA-Z0-9]/g, "")}-${dark ? "d" : "l"}`, chart);
3436
+ if (live) {
3437
+ setDrawn(naturalSize(svg));
3438
+ setFailed(false);
3439
+ }
3440
+ } catch {
3441
+ if (live) setFailed(true);
3442
+ }
3443
+ })();
3444
+ return () => {
3445
+ live = false;
3446
+ };
3447
+ }, [chart, dark, load, raw]);
3448
+ if (failed) return /* @__PURE__ */ jsx(CodeBlock, { code: chart, caption: "Diagram (shown as its source)", className: cn("my-6", className) });
3449
+ return /* @__PURE__ */ jsxs("figure", { ref, className: cn("not-prose my-6 overflow-hidden rounded-[1.25rem] border border-border bg-card", className), children: [
3450
+ drawn ? /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsx(
3451
+ "div",
3267
3452
  {
3268
- "aria-hidden": true,
3453
+ "data-fit": fits ? "" : void 0,
3269
3454
  className: cn(
3270
- "hidden gap-5 px-5 py-4 text-[0.875rem] font-medium text-muted-foreground",
3271
- wide ? "lg:grid lg:px-8" : "md:grid md:px-8",
3272
- grid
3455
+ "flex justify-center p-6 [&_svg]:h-auto",
3456
+ fits ? "w-full [&_svg]:max-w-full" : "w-max min-w-full [&_svg]:max-w-none"
3273
3457
  ),
3274
- children: [
3275
- /* @__PURE__ */ jsx("span", { children: propertyHeading }),
3276
- columns.map((c) => /* @__PURE__ */ jsx("span", { className: cn(c.highlight && cn(TINT, "-my-4 px-4 py-4 text-oca-accent-ink")), children: c.label }, c.key))
3277
- ]
3458
+ role: "img",
3459
+ "aria-label": typeof caption === "string" ? caption : "Diagram",
3460
+ dangerouslySetInnerHTML: { __html: drawn.svg }
3278
3461
  }
3279
- ),
3280
- rows.map((r, ri) => /* @__PURE__ */ 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: [
3281
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
3282
- /* @__PURE__ */ jsx("span", { className: "oca-title-sm", children: r.label }),
3283
- r.note ? /* @__PURE__ */ jsx("span", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: r.note }) : null
3284
- ] }),
3285
- /* @__PURE__ */ jsx("div", { className: cn("grid grid-cols-2 gap-1", desk === "lg" ? "lg:contents" : "md:contents"), children: columns.map((c) => {
3286
- return /* @__PURE__ */ jsxs(
3287
- "div",
3288
- {
3289
- style: { "--oca-order": ordered.indexOf(c) },
3290
- className: cn(
3291
- // Two rows of the pair's grid (name, answer), so answers line up
3292
- // across a pair even when one name wraps.
3293
- "order-[var(--oca-order)] row-span-2 grid min-w-0 grid-rows-subgrid gap-1 rounded-xl px-3 py-2.5",
3294
- 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",
3295
- c.highlight ? cn(
3296
- TINT,
3297
- "col-span-2",
3298
- 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"
3299
- ) : desk === "lg" ? "lg:p-0" : "md:p-0"
3300
- ),
3301
- children: [
3302
- /* @__PURE__ */ jsx(
3303
- "span",
3304
- {
3305
- className: cn(
3306
- "text-[0.8125rem]",
3307
- c.highlight ? "text-oca-accent-ink" : "text-muted-foreground",
3308
- desk === "lg" ? "lg:sr-only" : "md:sr-only"
3309
- ),
3310
- children: c.label
3311
- }
3312
- ),
3313
- /* @__PURE__ */ jsx("span", { className: cn("text-[0.9375rem]", c.highlight && "font-medium"), children: r.values[c.key] ?? "\u2014" })
3314
- ]
3315
- },
3316
- c.key
3317
- );
3318
- }) })
3319
- ] }, ri))
3462
+ ) }) : /* @__PURE__ */ jsx("div", { role: "status", "aria-label": "Drawing the diagram", className: "p-6", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-40 w-full rounded-xl" }) }),
3463
+ caption ? /* @__PURE__ */ jsx("figcaption", { className: "border-t border-border px-5 py-3 text-[0.8125rem] text-muted-foreground", children: caption }) : null
3320
3464
  ] });
3321
3465
  }
3322
- var CHECK = {
3323
- ok: { word: "Passed", icon: /* @__PURE__ */ jsx(CircleCheck, {}), tone: "text-success" },
3324
- fail: { word: "Failed", icon: /* @__PURE__ */ jsx(CircleX, {}), tone: "text-destructive" },
3325
- pending: { word: "Pending", icon: /* @__PURE__ */ jsx(Clock, {}), tone: "text-oca-accent-ink" },
3326
- skipped: { word: "Skipped", icon: /* @__PURE__ */ jsx(CircleMinus, {}), tone: "text-muted-foreground" },
3327
- unchecked: { word: "Not checked", icon: /* @__PURE__ */ jsx(CircleDashed, {}), tone: "text-oca-subtle" }
3466
+ var HEADING = {
3467
+ h1: "oca-display-3 mb-4 text-foreground",
3468
+ h2: "mb-3 mt-12 text-[1.375rem] font-medium leading-tight tracking-[-0.015em] text-foreground md:text-[1.5rem]",
3469
+ h3: "mb-2 mt-9 text-[1.125rem] font-medium leading-snug tracking-[-0.01em] text-foreground",
3470
+ h4: "mb-2 mt-7 text-[1rem] font-medium leading-snug text-foreground"
3328
3471
  };
3329
- function VerifyReport({
3330
- verdict,
3331
- title,
3332
- summary,
3333
- checks,
3334
- facts,
3335
- notChecked,
3336
- actions,
3337
- as: Heading = "h2",
3338
- className
3472
+ function DocsHeading({
3473
+ as: Tag,
3474
+ id,
3475
+ children,
3476
+ className,
3477
+ ...props
3339
3478
  }) {
3340
- return /* @__PURE__ */ jsxs(
3341
- "section",
3342
- {
3343
- "aria-label": "Verification result",
3344
- className: cn("overflow-hidden rounded-[1.25rem] border border-border bg-card", className),
3345
- children: [
3346
- /* @__PURE__ */ jsxs("header", { className: "flex flex-col items-start gap-3 p-6 md:p-8", children: [
3347
- /* @__PURE__ */ jsx(StatusBadge, { status: verdict }),
3348
- /* @__PURE__ */ jsx(Heading, { className: "oca-display-3", children: title }),
3349
- summary ? /* @__PURE__ */ jsx("p", { className: "oca-body max-w-[40rem]", children: summary }) : null
3350
- ] }),
3351
- /* @__PURE__ */ jsx("ul", { "aria-label": "Checks", className: "divide-y divide-border border-t border-border", children: checks.map((c, i) => {
3352
- const k = CHECK[c.state];
3353
- return /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-3 px-6 py-3.5 md:px-8", children: [
3354
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("mt-0.5 shrink-0 [&_svg]:size-[1.125rem]", k.tone), children: k.icon }),
3355
- /* @__PURE__ */ 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: [
3356
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
3357
- /* @__PURE__ */ jsx("span", { className: "text-[0.9375rem]", children: c.label }),
3358
- c.note ? /* @__PURE__ */ jsx("span", { className: "break-words text-[0.8125rem] leading-snug text-muted-foreground", children: c.note }) : null
3359
- ] }),
3360
- /* @__PURE__ */ jsx(
3361
- "span",
3362
- {
3363
- className: cn(
3364
- "shrink-0 text-[0.8125rem]",
3365
- c.state === "fail" ? "text-destructive" : "text-muted-foreground"
3366
- ),
3367
- children: k.word
3368
- }
3369
- )
3370
- ] })
3371
- ] }, i);
3372
- }) }),
3373
- facts && facts.length > 0 ? /* @__PURE__ */ jsx(KeyValueList, { items: facts, className: "rounded-none border-x-0 border-b-0 bg-transparent [&>div]:px-6 md:[&>div]:px-8" }) : null,
3374
- notChecked && notChecked.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 border-t border-border bg-muted/50 px-6 py-5 md:px-8", children: [
3375
- /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] font-medium", children: "What this did not check" }),
3376
- /* @__PURE__ */ 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__ */ jsx("li", { children: n }, i)) })
3377
- ] }) : null,
3378
- actions ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3 border-t border-border px-6 py-5 md:px-8", children: actions }) : null
3379
- ]
3380
- }
3381
- );
3382
- }
3383
- function SignMessage({
3384
- lead,
3385
- address,
3386
- message,
3387
- wallets,
3388
- busy = false,
3389
- error,
3390
- submitLabel = "Confirm",
3391
- secondary,
3392
- onSignature,
3393
- className
3394
- }) {
3395
- const [pasted, setPasted] = useState("");
3396
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-5", className), children: [
3397
- lead ? /* @__PURE__ */ jsx("p", { className: "text-[0.9375rem] leading-relaxed", children: lead }) : null,
3398
- wallets ? /* @__PURE__ */ jsxs(Fragment, { children: [
3399
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: wallets }),
3400
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 text-[0.8125rem] text-muted-foreground", children: [
3401
- /* @__PURE__ */ jsx("span", { className: "h-px flex-1 bg-border" }),
3402
- "or sign it in any wallet",
3403
- /* @__PURE__ */ jsx("span", { className: "h-px flex-1 bg-border" })
3404
- ] })
3405
- ] }) : null,
3406
- /* @__PURE__ */ jsx(CodeBlock, { code: message, caption: "Message to sign" }),
3407
- /* @__PURE__ */ jsxs(
3408
- "form",
3479
+ return /* @__PURE__ */ jsxs(Tag, { id, className: cn("group scroll-mt-28", HEADING[Tag], className), ...props, children: [
3480
+ /* @__PURE__ */ jsx("span", { "data-heading-text": "", children }),
3481
+ id && Tag !== "h1" ? /* @__PURE__ */ jsxs(
3482
+ "a",
3409
3483
  {
3410
- className: "flex flex-col gap-4",
3411
- onSubmit: (e) => {
3412
- e.preventDefault();
3413
- if (pasted.trim()) onSignature(pasted.trim());
3414
- },
3484
+ href: `#${id}`,
3485
+ className: "ml-2 inline-block rounded-md px-1 align-baseline text-[0.85em] font-normal text-oca-subtle no-underline opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100",
3415
3486
  children: [
3416
- /* @__PURE__ */ jsx(
3417
- Field,
3418
- {
3419
- label: "Signature",
3420
- error,
3421
- hint: /* @__PURE__ */ jsxs(Fragment, { children: [
3422
- "From your wallet\u2019s \u201Csign message\u201D (BIP-322), signed by",
3423
- " ",
3424
- /* @__PURE__ */ jsx("span", { className: "break-all font-mono", children: address }),
3425
- "."
3426
- ] }),
3427
- children: /* @__PURE__ */ jsx(
3428
- Textarea,
3429
- {
3430
- value: pasted,
3431
- onChange: (e) => setPasted(e.target.value),
3432
- rows: 3,
3433
- spellCheck: false,
3434
- className: "min-h-24 font-mono text-base md:text-[0.8125rem]"
3435
- }
3436
- )
3437
- }
3438
- ),
3439
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
3440
- /* @__PURE__ */ jsx(Button, { type: "submit", loading: busy, disabled: !pasted.trim(), children: submitLabel }),
3441
- secondary
3442
- ] })
3487
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "#" }),
3488
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Link to this section" })
3443
3489
  ]
3444
3490
  }
3445
- )
3446
- ] });
3447
- }
3448
- var isInternal = (href) => href.startsWith("/") || href.startsWith("#");
3449
- function DocLink({ href, className, children, ...rest }) {
3450
- return isInternal(href) ? /* @__PURE__ */ jsx(Link, { href, className, ...rest, children }) : /* @__PURE__ */ jsx("a", { href, className, ...rest, children });
3451
- }
3452
- function Breadcrumbs({ items, action, className }) {
3453
- return /* @__PURE__ */ jsxs("div", { className: cn("flex min-h-11 items-center justify-between gap-4 sm:min-h-0", className), children: [
3454
- /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "min-w-0", children: /* @__PURE__ */ jsx("ol", { className: "flex min-w-0 items-center gap-1.5 text-[0.875rem] text-muted-foreground", children: items.map((c, i) => {
3455
- const last = i === items.length - 1;
3456
- return /* @__PURE__ */ jsxs("li", { className: cn("flex items-center gap-1.5", last ? "min-w-0" : "shrink-0"), children: [
3457
- c.href && !last ? /* @__PURE__ */ jsx(DocLink, { href: c.href, className: "inline-flex min-h-11 items-center transition-colors hover:text-foreground sm:min-h-0", children: c.label }) : /* @__PURE__ */ jsx("span", { "aria-current": last ? "page" : void 0, className: cn("truncate", last && "text-foreground"), children: c.label }),
3458
- !last ? /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-oca-subtle" }) : null
3459
- ] }, i);
3460
- }) }) }),
3461
- action ? /* @__PURE__ */ jsx("div", { className: "shrink-0 text-[0.875rem]", children: action }) : null
3462
- ] });
3463
- }
3464
- function DocsPager({ prev, next, className }) {
3465
- if (!prev && !next) return null;
3466
- const card = (l, dir) => /* @__PURE__ */ jsxs(
3467
- DocLink,
3468
- {
3469
- href: l.href,
3470
- className: cn(
3471
- "group flex min-h-20 flex-col justify-center gap-1 rounded-2xl border border-border bg-card px-5 py-4 transition-colors hover:border-oca-hairline-strong",
3472
- dir === "next" && "items-end text-right sm:col-start-2"
3473
- ),
3474
- children: [
3475
- /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-[0.8125rem] text-muted-foreground", children: [
3476
- dir === "prev" ? /* @__PURE__ */ jsx(ArrowLeft, { "aria-hidden": true, className: "size-3.5" }) : null,
3477
- dir === "prev" ? "Previous" : "Next",
3478
- l.section ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\xB7" }) : null,
3479
- l.section ? /* @__PURE__ */ jsx("span", { className: "truncate", children: l.section }) : null,
3480
- dir === "next" ? /* @__PURE__ */ jsx(ArrowRight, { "aria-hidden": true, className: "size-3.5" }) : null
3481
- ] }),
3482
- /* @__PURE__ */ jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: l.label })
3483
- ]
3484
- }
3485
- );
3486
- return /* @__PURE__ */ jsxs("nav", { "aria-label": "Previous and next page", className: cn("grid grid-cols-1 gap-3 border-t border-border pt-8 sm:grid-cols-2", className), children: [
3487
- prev ? card(prev, "prev") : null,
3488
- next ? card(next, "next") : null
3491
+ ) : null
3489
3492
  ] });
3490
3493
  }
3491
- function useHeadings(selector = "#docs-content", key) {
3492
- const [items, setItems] = useState([]);
3493
- useEffect(() => {
3494
- const read = () => {
3495
- const root = document.querySelector(selector);
3496
- if (!root) return setItems([]);
3497
- setItems(
3498
- Array.from(root.querySelectorAll("h2[id], h3[id]")).map((h) => ({
3499
- id: h.id,
3500
- // The anchor link's "#" is not part of the name.
3501
- label: (h.querySelector("[data-heading-text]") ?? h).textContent?.trim() ?? "",
3502
- level: h.tagName === "H3" ? 3 : 2
3503
- }))
3504
- );
3505
- };
3506
- const raf = requestAnimationFrame(read);
3507
- const t = setTimeout(read, 80);
3508
- return () => {
3509
- cancelAnimationFrame(raf);
3510
- clearTimeout(t);
3511
- };
3512
- }, [selector, key]);
3513
- const activeId = useActiveHeading(items.map((i) => i.id));
3514
- return { items, activeId };
3515
- }
3516
- function OnThisPage({
3517
- items,
3518
- activeId,
3519
- title = "On this page",
3520
- onNavigate,
3521
- className
3522
- }) {
3523
- const id = useId();
3524
- if (items.length === 0) return null;
3525
- return (
3526
- // With no visible title (a folded list under its own summary) the name is still "On this page".
3527
- /* @__PURE__ */ jsxs("nav", { "aria-labelledby": title ? id : void 0, "aria-label": title ? void 0 : "On this page", className, children: [
3528
- title ? /* @__PURE__ */ jsx("p", { id, className: "mb-3 text-[0.875rem] font-medium", children: title }) : null,
3529
- /* @__PURE__ */ jsx("ul", { children: items.map((t) => {
3530
- const on = t.id === activeId;
3531
- return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
3532
- "a",
3533
- {
3534
- href: `#${t.id}`,
3535
- onClick: onNavigate,
3536
- "aria-current": on ? "location" : void 0,
3537
- className: cn(
3538
- "block border-l py-1.5 text-[0.875rem] leading-snug transition-colors",
3539
- t.level === 3 ? "pl-7" : "pl-4",
3540
- on ? "border-foreground text-foreground" : "border-border text-muted-foreground hover:text-foreground"
3541
- ),
3542
- children: t.label
3543
- }
3544
- ) }, t.id);
3545
- }) })
3546
- ] })
3547
- );
3548
- }
3549
- var CALLOUT_TONE = { note: "neutral", warning: "brand", danger: "danger" };
3550
- function Callout({
3551
- tone = "note",
3494
+ function ProtocolHero({
3495
+ protocol: protocol2,
3552
3496
  title,
3497
+ lead,
3498
+ actions,
3499
+ art,
3553
3500
  children,
3554
3501
  className
3555
3502
  }) {
3503
+ const p = protocolSite(protocol2);
3556
3504
  return /* @__PURE__ */ jsx(
3557
- Notice,
3505
+ PageHero,
3558
3506
  {
3559
- tone: CALLOUT_TONE[tone],
3507
+ className,
3508
+ eyebrow: `Protocol \xB7 ${p.verb}`,
3560
3509
  title,
3561
- role: "note",
3562
- className: cn("my-6 [&_p]:my-0 [&_p]:text-[0.9375rem] [&_p]:leading-relaxed [&_p+p]:mt-3", className),
3563
- children
3510
+ lead,
3511
+ actions,
3512
+ art,
3513
+ children: p.status !== "live" || children ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-4", children: [
3514
+ p.status !== "live" ? /* @__PURE__ */ jsx(StatusBadge, { status: p.status }) : null,
3515
+ children
3516
+ ] }) : null
3564
3517
  }
3565
3518
  );
3566
3519
  }
3567
- function Step({ title, id, children }) {
3568
- return /* @__PURE__ */ jsxs("li", { className: "relative pb-8 pl-11 last:pb-0 [counter-increment:oca-step]", children: [
3569
- /* @__PURE__ */ jsx(
3570
- "span",
3571
- {
3572
- "aria-hidden": true,
3573
- className: "absolute left-0 top-0 flex size-7 items-center justify-center rounded-full border border-oca-hairline-strong bg-card text-[0.8125rem] oca-tabular text-foreground before:content-[counter(oca-step)]"
3574
- }
3575
- ),
3576
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "absolute bottom-1 left-[0.8125rem] top-9 w-px bg-border" }),
3577
- /* @__PURE__ */ jsx("h3", { id, className: "scroll-mt-28 pt-0.5 text-[1.0625rem] font-medium leading-snug tracking-[-0.008em] text-foreground", children: title }),
3578
- /* @__PURE__ */ jsx("div", { className: "mt-2 text-muted-foreground [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children })
3579
- ] });
3580
- }
3581
- function Steps({ children, className }) {
3582
- return /* @__PURE__ */ jsx("ol", { className: cn("not-prose my-8 flex flex-col [counter-reset:oca-step] [&>li:last-child>span:nth-child(2)]:hidden", className), children });
3583
- }
3584
- function LinkCard({
3585
- href,
3586
- title,
3587
- description,
3588
- icon,
3589
- meta,
3520
+ function ProtocolNav({
3521
+ current,
3522
+ link = "page",
3590
3523
  className
3591
3524
  }) {
3592
- const Arrow = isInternal(href) ? ArrowRight : ArrowUpRight;
3525
+ return /* @__PURE__ */ jsx("nav", { "aria-label": "Protocols", className, children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--background)", children: /* @__PURE__ */ jsx("ul", { className: "flex w-max min-w-full items-center gap-6 border-b border-border", children: PROTOCOLS.map((p) => {
3526
+ const on = p.slug === current;
3527
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
3528
+ "a",
3529
+ {
3530
+ href: link === "tool" ? p.toolHref : p.pageHref,
3531
+ "aria-current": on ? "page" : void 0,
3532
+ className: cn(
3533
+ "-mb-px inline-flex h-11 items-center border-b-2 text-[0.9375rem] transition-colors",
3534
+ on ? "border-foreground text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
3535
+ ),
3536
+ children: p.label
3537
+ }
3538
+ ) }, p.slug);
3539
+ }) }) }) });
3540
+ }
3541
+ var SPEC_FILE = {
3542
+ spec: {
3543
+ file: "SPEC.md",
3544
+ title: "Normative source",
3545
+ note: "This page is a human-readable summary. The authoritative copy lives in the spec repo. If the two ever drift, the repo wins."
3546
+ },
3547
+ security: {
3548
+ file: "SECURITY.md",
3549
+ title: "Normative threat model",
3550
+ note: "This page is the short form. The authoritative, numbered threat model lives in the spec repo."
3551
+ },
3552
+ rationale: {
3553
+ file: "WHY.md",
3554
+ title: "Design rationale",
3555
+ note: "This page is the short version. The full rationale and the rejected-design log live in the spec repo."
3556
+ }
3557
+ };
3558
+ function SpecCard(props) {
3559
+ return props.repo !== void 0 ? /* @__PURE__ */ jsx(SpecFileNote, { ...props }) : /* @__PURE__ */ jsx(ProtocolSpecCard, { ...props });
3560
+ }
3561
+ function SpecFileNote({ repo, file, kind = "spec", version, note, className }) {
3562
+ const d = SPEC_FILE[kind];
3563
+ const f = file ?? d.file;
3564
+ return /* @__PURE__ */ jsxs(Callout, { title: version ? `${d.title} \xB7 ${version}` : d.title, className, children: [
3565
+ /* @__PURE__ */ jsx("p", { children: note ?? d.note }),
3566
+ /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(TextLink, { href: `https://github.com/orangecheck/${repo}/blob/main/${f}`, className: "break-all font-mono text-[0.875rem]", children: `${repo}/${f}` }) })
3567
+ ] });
3568
+ }
3569
+ function ProtocolSpecCard({ protocol: protocol2, version, license, vectors, size = "md", className }) {
3570
+ const p = protocolSite(protocol2);
3571
+ const repo = `oc-${p.slug}-protocol`;
3572
+ const facts = [
3573
+ ["Version", version],
3574
+ ...license ? [["Licence", license]] : [],
3575
+ ["Nostr kind", p.kinds],
3576
+ ...vectors !== void 0 ? [["Test vectors", String(vectors)]] : []
3577
+ ];
3578
+ if (size === "sm") {
3579
+ return /* @__PURE__ */ jsxs(
3580
+ "a",
3581
+ {
3582
+ href: p.specHref,
3583
+ className: cn(
3584
+ "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",
3585
+ className
3586
+ ),
3587
+ children: [
3588
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-[0.8125rem] text-foreground", children: repo }),
3589
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: facts.map(([k, v]) => k === "Version" ? `v${v}` : k === "Nostr kind" ? `kind ${v}` : v).join(" \xB7 ") }),
3590
+ /* @__PURE__ */ jsxs("span", { className: "ml-auto flex items-center gap-1 text-muted-foreground group-hover:text-foreground", children: [
3591
+ "Read the spec ",
3592
+ /* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": true, className: "size-4" })
3593
+ ] })
3594
+ ]
3595
+ }
3596
+ );
3597
+ }
3598
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-6 rounded-[1.25rem] border border-border bg-card p-6 md:p-8", className), children: [
3599
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
3600
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
3601
+ /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] text-muted-foreground", children: "The spec" }),
3602
+ /* @__PURE__ */ jsx("h3", { className: "oca-title break-all font-mono text-[1.0625rem] tracking-normal", children: repo })
3603
+ ] }),
3604
+ p.status !== "live" ? /* @__PURE__ */ jsx(StatusBadge, { status: p.status }) : null
3605
+ ] }),
3606
+ /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-4", children: facts.map(([k, v]) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
3607
+ /* @__PURE__ */ jsx("dt", { className: "text-[0.8125rem] text-muted-foreground", children: k }),
3608
+ /* @__PURE__ */ jsx("dd", { className: "oca-tabular text-[1.0625rem]", children: v })
3609
+ ] }, k)) }),
3610
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { asChild: true, variant: "secondary", size: "sm", children: /* @__PURE__ */ jsxs("a", { href: p.specHref, children: [
3611
+ "Read the spec ",
3612
+ /* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": true })
3613
+ ] }) }) })
3614
+ ] });
3615
+ }
3616
+ function VerifyBox({
3617
+ action,
3618
+ param = "q",
3619
+ title,
3620
+ description,
3621
+ label = "Id, envelope or link",
3622
+ placeholder,
3623
+ hint,
3624
+ submitLabel = "Verify",
3625
+ multiline = false,
3626
+ onVerify,
3627
+ className
3628
+ }) {
3629
+ const [value, setValue] = useState("");
3630
+ const submit = (e) => {
3631
+ if (!onVerify) return;
3632
+ e.preventDefault();
3633
+ if (value.trim()) onVerify(value.trim());
3634
+ };
3635
+ const button = /* @__PURE__ */ jsx(Button, { type: "submit", className: multiline ? void 0 : "w-full sm:w-auto", children: submitLabel });
3593
3636
  return /* @__PURE__ */ jsxs(
3594
- DocLink,
3637
+ "form",
3595
3638
  {
3596
- href,
3597
- className: cn(
3598
- "group flex h-full flex-col gap-3 rounded-[1.25rem] border border-border bg-card p-5 transition-colors hover:border-oca-hairline-strong",
3599
- className
3600
- ),
3639
+ action,
3640
+ method: "get",
3641
+ onSubmit: submit,
3642
+ className: cn("flex flex-col gap-5 rounded-[1.25rem] border border-border bg-card p-6 md:p-8", className),
3601
3643
  children: [
3602
- /* @__PURE__ */ jsxs("span", { className: "flex items-start justify-between gap-3", children: [
3603
- icon ? /* @__PURE__ */ jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-xl bg-muted text-foreground [&_svg]:size-[1.125rem]", children: icon }) : /* @__PURE__ */ jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }),
3604
- /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [
3605
- meta,
3606
- /* @__PURE__ */ jsx(Arrow, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-foreground" })
3607
- ] })
3608
- ] }),
3609
- icon ? /* @__PURE__ */ jsx("span", { className: "text-[1rem] font-medium leading-snug text-foreground", children: title }) : null,
3610
- description ? /* @__PURE__ */ jsx("span", { className: "text-[0.9375rem] leading-relaxed text-muted-foreground", children: description }) : null
3644
+ title || description ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
3645
+ title ? /* @__PURE__ */ jsx("h3", { className: "oca-title", children: title }) : null,
3646
+ description ? /* @__PURE__ */ jsx("p", { className: "oca-body text-[0.9375rem]", children: description }) : null
3647
+ ] }) : null,
3648
+ multiline ? /* @__PURE__ */ jsxs(Fragment, { children: [
3649
+ /* @__PURE__ */ jsx(Field, { label, hint, children: /* @__PURE__ */ jsx(
3650
+ Textarea,
3651
+ {
3652
+ name: param,
3653
+ required: true,
3654
+ value,
3655
+ onChange: (e) => setValue(e.target.value),
3656
+ placeholder,
3657
+ spellCheck: false,
3658
+ className: "min-h-32 font-mono text-base md:text-[0.8125rem]"
3659
+ }
3660
+ ) }),
3661
+ /* @__PURE__ */ jsx("div", { children: button })
3662
+ ] }) : /* @__PURE__ */ jsx(Field, { label, hint, action: button, children: /* @__PURE__ */ jsx(
3663
+ Input,
3664
+ {
3665
+ name: param,
3666
+ required: true,
3667
+ value,
3668
+ onChange: (e) => setValue(e.target.value),
3669
+ placeholder,
3670
+ spellCheck: false,
3671
+ autoComplete: "off",
3672
+ className: "font-mono text-base md:text-[0.875rem]"
3673
+ }
3674
+ ) })
3611
3675
  ]
3612
3676
  }
3613
3677
  );
3614
3678
  }
3615
- function CardGrid({ columns = 2, children, className }) {
3616
- return /* @__PURE__ */ jsx("div", { className: cn("not-prose my-6 grid grid-cols-1 gap-3 sm:grid-cols-2", columns === 3 && "lg:grid-cols-3", className), children });
3617
- }
3618
- function MdxTable({ className, ...props }) {
3619
- return /* @__PURE__ */ jsx("div", { className: "not-prose my-6 overflow-hidden rounded-2xl border border-border bg-card", children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsx(
3620
- "table",
3621
- {
3622
- className: cn(
3623
- "w-full border-collapse text-left text-[0.875rem] leading-relaxed",
3624
- "[&_th]:whitespace-nowrap [&_th]:border-b [&_th]:border-oca-hairline-strong [&_th]:bg-oca-table-head [&_th]:px-4 [&_th]:py-2.5 [&_th]:text-[0.8125rem] [&_th]:font-medium [&_th]:text-foreground",
3625
- "[&_td]:border-t [&_td]:border-border [&_td]:px-4 [&_td]:py-2.5 [&_td]:align-top [&_td]:text-muted-foreground [&_tbody_tr:first-child_td]:border-t-0",
3626
- "[&_td_code]:bg-transparent [&_td_code]:p-0 [&_td_code]:text-foreground [&_td:first-child]:text-foreground",
3627
- "[&_[align=center]]:text-center [&_[align=right]]:text-right",
3628
- // On a phone a cell keeps a readable width; the table scrolls instead of crushing it.
3629
- "max-sm:[&_td]:min-w-[9rem]",
3630
- className
3631
- ),
3632
- ...props
3633
- }
3634
- ) }) });
3635
- }
3636
- function ApiTable({
3679
+ var TINT = "bg-[color-mix(in_oklab,var(--oca-orange)_9%,var(--card))]";
3680
+ function ComparisonTable({
3681
+ columns,
3637
3682
  rows,
3638
- caption,
3639
- nameHeader = "Name",
3683
+ label,
3684
+ propertyHeading = "Property",
3640
3685
  className
3641
3686
  }) {
3642
- const hasDefault = rows.some((r) => r.default !== void 0);
3643
- const marks = (r) => /* @__PURE__ */ jsxs(Fragment, { children: [
3644
- r.required ? /* @__PURE__ */ jsx("span", { className: "text-[0.75rem] text-oca-accent-ink", children: "Required" }) : null,
3645
- r.deprecated ? /* @__PURE__ */ jsx(Badge, { tone: "muted", children: "Deprecated" }) : null,
3646
- r.status ? /* @__PURE__ */ jsx(StatusBadge, { status: r.status }) : null
3647
- ] });
3648
- return /* @__PURE__ */ jsxs("div", { className: cn("not-prose my-6", className), children: [
3649
- /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-2xl border border-border bg-card max-sm:hidden", children: /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-left text-[0.875rem]", children: [
3650
- caption ? /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }) : null,
3651
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-oca-hairline-strong bg-oca-table-head text-[0.8125rem]", children: [
3652
- /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: nameHeader }),
3653
- /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Type" }),
3654
- hasDefault ? /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Default" }) : null,
3655
- /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2.5 font-medium", children: "Description" })
3656
- ] }) }),
3657
- /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-border", children: rows.map((r) => /* @__PURE__ */ jsxs("tr", { className: "align-top", children: [
3658
- /* @__PURE__ */ jsx("th", { scope: "row", className: "px-4 py-3 text-left font-normal", children: /* @__PURE__ */ jsxs("span", { className: "flex flex-col items-start gap-1", children: [
3659
- /* @__PURE__ */ jsx("code", { className: cn("font-mono text-[0.8125rem] text-foreground", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
3660
- marks(r)
3661
- ] }) }),
3662
- /* @__PURE__ */ jsx("td", { className: "px-4 py-3 font-mono text-[0.8125rem] text-muted-foreground", children: r.type ?? "\u2014" }),
3663
- hasDefault ? /* @__PURE__ */ jsx("td", { className: "px-4 py-3 font-mono text-[0.8125rem] text-muted-foreground", children: r.default ?? "\u2014" }) : null,
3664
- /* @__PURE__ */ jsx("td", { className: "px-4 py-3 leading-relaxed text-muted-foreground", children: r.description })
3665
- ] }, r.name)) })
3666
- ] }) }) }),
3667
- /* @__PURE__ */ jsx("ul", { "aria-label": caption, className: "divide-y divide-border rounded-2xl border border-border bg-card sm:hidden", children: rows.map((r) => /* @__PURE__ */ jsxs("li", { className: "flex flex-col gap-1.5 px-4 py-3.5", children: [
3668
- /* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [
3669
- /* @__PURE__ */ jsx("code", { className: cn("font-mono text-[0.875rem] text-foreground", r.deprecated && "line-through decoration-oca-subtle"), children: r.name }),
3670
- r.type ? /* @__PURE__ */ jsx("code", { className: "break-all font-mono text-[0.8125rem] text-muted-foreground", children: r.type }) : null
3671
- ] }),
3672
- /* @__PURE__ */ jsx("span", { className: "flex flex-wrap items-center gap-2 empty:hidden", children: marks(r) }),
3673
- r.description ? /* @__PURE__ */ jsx("span", { className: "text-[0.875rem] leading-relaxed text-muted-foreground", children: r.description }) : null,
3674
- r.default !== void 0 ? /* @__PURE__ */ jsxs("span", { className: "text-[0.8125rem] text-muted-foreground", children: [
3675
- "Default ",
3676
- /* @__PURE__ */ jsx("code", { className: "font-mono text-foreground", children: r.default })
3677
- ] }) : null
3678
- ] }, r.name)) })
3679
- ] });
3680
- }
3681
- function useDarkMode() {
3682
- const [dark, setDark] = useState(false);
3683
- useEffect(() => {
3684
- const root = document.documentElement;
3685
- const read = () => setDark(root.classList.contains("dark"));
3686
- read();
3687
- const mo = new MutationObserver(read);
3688
- mo.observe(root, { attributes: true, attributeFilter: ["class"] });
3689
- return () => mo.disconnect();
3690
- }, []);
3691
- return dark;
3692
- }
3693
- function mermaidTheme(el) {
3694
- const css = getComputedStyle(el);
3695
- const v = (name) => css.getPropertyValue(name).trim();
3696
- const card = v("--card");
3697
- const muted = v("--muted");
3698
- const text = v("--foreground");
3699
- const subtle = v("--muted-foreground");
3700
- const line = v("--input");
3701
- const hair = v("--oca-hairline-strong");
3702
- return {
3703
- background: "transparent",
3704
- fontFamily: css.fontFamily,
3705
- fontSize: "14px",
3706
- textColor: text,
3707
- mainBkg: card,
3708
- primaryColor: card,
3709
- primaryTextColor: text,
3710
- primaryBorderColor: hair,
3711
- secondaryColor: muted,
3712
- secondaryTextColor: text,
3713
- secondaryBorderColor: hair,
3714
- tertiaryColor: muted,
3715
- tertiaryTextColor: text,
3716
- tertiaryBorderColor: hair,
3717
- nodeBorder: hair,
3718
- lineColor: line,
3719
- edgeLabelBackground: card,
3720
- clusterBkg: muted,
3721
- clusterBorder: hair,
3722
- titleColor: text,
3723
- noteBkgColor: muted,
3724
- noteTextColor: text,
3725
- noteBorderColor: hair,
3726
- actorBkg: card,
3727
- actorBorder: hair,
3728
- actorTextColor: text,
3729
- actorLineColor: line,
3730
- signalColor: text,
3731
- signalTextColor: text,
3732
- labelBoxBkgColor: card,
3733
- labelBoxBorderColor: hair,
3734
- labelTextColor: text,
3735
- loopTextColor: subtle,
3736
- activationBkgColor: muted,
3737
- activationBorderColor: hair,
3738
- sequenceNumberColor: card
3687
+ const wide = columns.length > 3;
3688
+ const grid = wide ? "lg:grid lg:grid-cols-[var(--oca-compare)]" : "md:grid md:grid-cols-[var(--oca-compare)]";
3689
+ const desk = wide ? "lg" : "md";
3690
+ const style = {
3691
+ // The argued-for column gets a little more room: its answers carry the page.
3692
+ "--oca-compare": ["minmax(0, 1.4fr)", ...columns.map((c) => c.highlight ? "minmax(0, 1.3fr)" : "minmax(0, 1fr)")].join(" ")
3739
3693
  };
3740
- }
3741
- function naturalSize(svg) {
3742
- const w = svg.match(/viewBox="[\d.-]+ [\d.-]+ ([\d.]+) [\d.]+"/)?.[1];
3743
- if (!w) return svg;
3744
- return svg.replace(/<svg([^>]*?)\swidth="100%"/, `<svg$1 width="${Math.ceil(Number(w))}"`).replace(/max-width:\s*[\d.]+px;?/, "");
3745
- }
3746
- function Diagram({ chart, caption, load, className }) {
3747
- const ref = useRef(null);
3748
- const dark = useDarkMode();
3749
- const raw = useId();
3750
- const [svg, setSvg] = useState(null);
3751
- const [failed, setFailed] = useState(false);
3752
- useEffect(() => {
3753
- let live = true;
3754
- const el = ref.current;
3755
- if (!el) return;
3756
- (async () => {
3757
- try {
3758
- const mod = await load();
3759
- const mermaid = "default" in mod ? mod.default : mod;
3760
- mermaid.initialize({ startOnLoad: false, securityLevel: "strict", theme: "base", themeVariables: mermaidTheme(el) });
3761
- const { svg: drawn } = await mermaid.render(`oca-diagram-${raw.replace(/[^a-zA-Z0-9]/g, "")}-${dark ? "d" : "l"}`, chart);
3762
- if (live) {
3763
- setSvg(naturalSize(drawn));
3764
- setFailed(false);
3765
- }
3766
- } catch {
3767
- if (live) setFailed(true);
3768
- }
3769
- })();
3770
- return () => {
3771
- live = false;
3772
- };
3773
- }, [chart, dark, load, raw]);
3774
- if (failed) return /* @__PURE__ */ jsx(CodeBlock, { code: chart, caption: "Diagram (shown as its source)", className: cn("my-6", className) });
3775
- return /* @__PURE__ */ jsxs("figure", { ref, className: cn("not-prose my-6 overflow-hidden rounded-[1.25rem] border border-border bg-card", className), children: [
3776
- svg ? /* @__PURE__ */ jsx(ScrollFade, { fade: "var(--card)", children: /* @__PURE__ */ jsx(
3777
- "div",
3694
+ const ordered = [...columns].sort((a, b) => Number(Boolean(b.highlight)) - Number(Boolean(a.highlight)));
3695
+ return /* @__PURE__ */ jsxs("ul", { "aria-label": label, style, className: cn("divide-y divide-border rounded-[1.25rem] border border-border bg-card", className), children: [
3696
+ /* @__PURE__ */ jsxs(
3697
+ "li",
3778
3698
  {
3779
- className: "flex w-max min-w-full justify-center p-6 [&_svg]:h-auto [&_svg]:max-w-none",
3780
- role: "img",
3781
- "aria-label": typeof caption === "string" ? caption : "Diagram",
3782
- dangerouslySetInnerHTML: { __html: svg }
3699
+ "aria-hidden": true,
3700
+ className: cn(
3701
+ "hidden gap-5 px-5 py-4 text-[0.875rem] font-medium text-muted-foreground",
3702
+ wide ? "lg:grid lg:px-8" : "md:grid md:px-8",
3703
+ grid
3704
+ ),
3705
+ children: [
3706
+ /* @__PURE__ */ jsx("span", { children: propertyHeading }),
3707
+ columns.map((c) => /* @__PURE__ */ jsx("span", { className: cn(c.highlight && cn(TINT, "-my-4 px-4 py-4 text-oca-accent-ink")), children: c.label }, c.key))
3708
+ ]
3783
3709
  }
3784
- ) }) : /* @__PURE__ */ jsx("div", { role: "status", "aria-label": "Drawing the diagram", className: "p-6", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-40 w-full rounded-xl" }) }),
3785
- caption ? /* @__PURE__ */ jsx("figcaption", { className: "border-t border-border px-5 py-3 text-[0.8125rem] text-muted-foreground", children: caption }) : null
3710
+ ),
3711
+ rows.map((r, ri) => /* @__PURE__ */ 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: [
3712
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
3713
+ /* @__PURE__ */ jsx("span", { className: "oca-title-sm", children: r.label }),
3714
+ r.note ? /* @__PURE__ */ jsx("span", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: r.note }) : null
3715
+ ] }),
3716
+ /* @__PURE__ */ jsx("div", { className: cn("grid grid-cols-2 gap-1", desk === "lg" ? "lg:contents" : "md:contents"), children: columns.map((c) => {
3717
+ return /* @__PURE__ */ jsxs(
3718
+ "div",
3719
+ {
3720
+ style: { "--oca-order": ordered.indexOf(c) },
3721
+ className: cn(
3722
+ // Two rows of the pair's grid (name, answer), so answers line up
3723
+ // across a pair even when one name wraps.
3724
+ "order-[var(--oca-order)] row-span-2 grid min-w-0 grid-rows-subgrid gap-1 rounded-xl px-3 py-2.5",
3725
+ 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",
3726
+ c.highlight ? cn(
3727
+ TINT,
3728
+ "col-span-2",
3729
+ 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"
3730
+ ) : desk === "lg" ? "lg:p-0" : "md:p-0"
3731
+ ),
3732
+ children: [
3733
+ /* @__PURE__ */ jsx(
3734
+ "span",
3735
+ {
3736
+ className: cn(
3737
+ "text-[0.8125rem]",
3738
+ c.highlight ? "text-oca-accent-ink" : "text-muted-foreground",
3739
+ desk === "lg" ? "lg:sr-only" : "md:sr-only"
3740
+ ),
3741
+ children: c.label
3742
+ }
3743
+ ),
3744
+ /* @__PURE__ */ jsx("span", { className: cn("text-[0.9375rem]", c.highlight && "font-medium"), children: r.values[c.key] ?? "\u2014" })
3745
+ ]
3746
+ },
3747
+ c.key
3748
+ );
3749
+ }) })
3750
+ ] }, ri))
3786
3751
  ] });
3787
3752
  }
3788
- var HEADING = {
3789
- h1: "oca-display-3 mb-4 text-foreground",
3790
- h2: "mb-3 mt-12 text-[1.375rem] font-medium leading-tight tracking-[-0.015em] text-foreground md:text-[1.5rem]",
3791
- h3: "mb-2 mt-9 text-[1.125rem] font-medium leading-snug tracking-[-0.01em] text-foreground",
3792
- h4: "mb-2 mt-7 text-[1rem] font-medium leading-snug text-foreground"
3753
+ var CHECK = {
3754
+ ok: { word: "Passed", icon: /* @__PURE__ */ jsx(CircleCheck, {}), tone: "text-success" },
3755
+ fail: { word: "Failed", icon: /* @__PURE__ */ jsx(CircleX, {}), tone: "text-destructive" },
3756
+ pending: { word: "Pending", icon: /* @__PURE__ */ jsx(Clock, {}), tone: "text-oca-accent-ink" },
3757
+ none: { word: "None", icon: /* @__PURE__ */ jsx(CircleSlash, {}), tone: "text-muted-foreground" },
3758
+ skipped: { word: "Skipped", icon: /* @__PURE__ */ jsx(CircleMinus, {}), tone: "text-muted-foreground" },
3759
+ unchecked: { word: "Not checked", icon: /* @__PURE__ */ jsx(CircleDashed, {}), tone: "text-oca-subtle" }
3793
3760
  };
3794
- function DocsHeading({
3795
- as: Tag,
3796
- id,
3797
- children,
3798
- className,
3799
- ...props
3761
+ function VerifyReport({
3762
+ verdict,
3763
+ title,
3764
+ summary,
3765
+ checks,
3766
+ facts,
3767
+ notChecked,
3768
+ actions,
3769
+ as: Heading = "h2",
3770
+ className
3800
3771
  }) {
3801
- return /* @__PURE__ */ jsxs(Tag, { id, className: cn("group scroll-mt-28", HEADING[Tag], className), ...props, children: [
3802
- /* @__PURE__ */ jsx("span", { "data-heading-text": "", children }),
3803
- id && Tag !== "h1" ? /* @__PURE__ */ jsxs(
3804
- "a",
3772
+ return /* @__PURE__ */ jsxs(
3773
+ "section",
3774
+ {
3775
+ "aria-label": "Verification result",
3776
+ className: cn("overflow-hidden rounded-[1.25rem] border border-border bg-card", className),
3777
+ children: [
3778
+ /* @__PURE__ */ jsxs("header", { className: "flex flex-col items-start gap-3 p-6 md:p-8", children: [
3779
+ /* @__PURE__ */ jsx(StatusBadge, { status: verdict }),
3780
+ /* @__PURE__ */ jsx(Heading, { className: "oca-display-3 [overflow-wrap:anywhere]", children: title }),
3781
+ summary ? /* @__PURE__ */ jsx("p", { className: "oca-body max-w-[40rem] [overflow-wrap:anywhere]", children: summary }) : null
3782
+ ] }),
3783
+ /* @__PURE__ */ jsx("ul", { "aria-label": "Checks", className: "divide-y divide-border border-t border-border", children: checks.map((c, i) => {
3784
+ const k = CHECK[c.state];
3785
+ return /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-3 px-6 py-3.5 md:px-8", children: [
3786
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("mt-0.5 shrink-0 [&_svg]:size-[1.125rem]", k.tone), children: k.icon }),
3787
+ /* @__PURE__ */ 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: [
3788
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
3789
+ /* @__PURE__ */ jsx("span", { className: "text-[0.9375rem]", children: c.label }),
3790
+ c.note ? /* @__PURE__ */ jsx("span", { className: "break-words text-[0.8125rem] leading-snug text-muted-foreground", children: c.note }) : null
3791
+ ] }),
3792
+ /* @__PURE__ */ jsx(
3793
+ "span",
3794
+ {
3795
+ className: cn(
3796
+ "shrink-0 text-[0.8125rem]",
3797
+ c.state === "fail" ? "text-destructive" : "text-muted-foreground"
3798
+ ),
3799
+ children: k.word
3800
+ }
3801
+ )
3802
+ ] })
3803
+ ] }, i);
3804
+ }) }),
3805
+ facts && facts.length > 0 ? /* @__PURE__ */ jsx(KeyValueList, { items: facts, className: "rounded-none border-x-0 border-b-0 bg-transparent [&>div]:px-6 md:[&>div]:px-8" }) : null,
3806
+ notChecked && notChecked.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 border-t border-border bg-muted/50 px-6 py-5 md:px-8", children: [
3807
+ /* @__PURE__ */ jsx("p", { className: "text-[0.875rem] font-medium", children: "What this did not check" }),
3808
+ /* @__PURE__ */ 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__ */ jsx("li", { children: n }, i)) })
3809
+ ] }) : null,
3810
+ actions ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3 border-t border-border px-6 py-5 md:px-8", children: actions }) : null
3811
+ ]
3812
+ }
3813
+ );
3814
+ }
3815
+ function SignMessage({
3816
+ lead,
3817
+ address,
3818
+ message,
3819
+ wallets,
3820
+ busy = false,
3821
+ error,
3822
+ submitLabel = "Confirm",
3823
+ secondary,
3824
+ onSignature,
3825
+ className
3826
+ }) {
3827
+ const [pasted, setPasted] = useState("");
3828
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-5", className), children: [
3829
+ lead ? /* @__PURE__ */ jsx("p", { className: "text-[0.9375rem] leading-relaxed", children: lead }) : null,
3830
+ wallets ? /* @__PURE__ */ jsxs(Fragment, { children: [
3831
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: wallets }),
3832
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 text-[0.8125rem] text-muted-foreground", children: [
3833
+ /* @__PURE__ */ jsx("span", { className: "h-px flex-1 bg-border" }),
3834
+ "or sign it in any wallet",
3835
+ /* @__PURE__ */ jsx("span", { className: "h-px flex-1 bg-border" })
3836
+ ] })
3837
+ ] }) : null,
3838
+ /* @__PURE__ */ jsx(CodeBlock, { code: message, caption: "Message to sign" }),
3839
+ /* @__PURE__ */ jsxs(
3840
+ "form",
3805
3841
  {
3806
- href: `#${id}`,
3807
- className: "ml-2 inline-block rounded-md px-1 align-baseline text-[0.85em] font-normal text-oca-subtle no-underline opacity-0 transition-opacity hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100",
3842
+ className: "flex flex-col gap-4",
3843
+ onSubmit: (e) => {
3844
+ e.preventDefault();
3845
+ if (pasted.trim()) onSignature(pasted.trim());
3846
+ },
3808
3847
  children: [
3809
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "#" }),
3810
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Link to this section" })
3848
+ /* @__PURE__ */ jsx(
3849
+ Field,
3850
+ {
3851
+ label: "Signature",
3852
+ error,
3853
+ hint: /* @__PURE__ */ jsxs(Fragment, { children: [
3854
+ "From your wallet\u2019s \u201Csign message\u201D (BIP-322), signed by",
3855
+ " ",
3856
+ /* @__PURE__ */ jsx("span", { className: "break-all font-mono", children: address }),
3857
+ "."
3858
+ ] }),
3859
+ children: /* @__PURE__ */ jsx(
3860
+ Textarea,
3861
+ {
3862
+ value: pasted,
3863
+ onChange: (e) => setPasted(e.target.value),
3864
+ rows: 3,
3865
+ spellCheck: false,
3866
+ className: "min-h-24 font-mono text-base md:text-[0.8125rem]"
3867
+ }
3868
+ )
3869
+ }
3870
+ ),
3871
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
3872
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading: busy, disabled: !pasted.trim(), children: submitLabel }),
3873
+ secondary
3874
+ ] })
3811
3875
  ]
3812
3876
  }
3813
- ) : null
3877
+ )
3814
3878
  ] });
3815
3879
  }
3816
3880
  function useMacKeys() {