@orangecheck/app-design 1.0.0 → 1.1.1

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 (66) hide show
  1. package/README.md +21 -5
  2. package/dist/chrome.d.mts +31 -42
  3. package/dist/chrome.d.ts +31 -42
  4. package/dist/chrome.js +502 -24
  5. package/dist/chrome.js.map +1 -1
  6. package/dist/chrome.mjs +497 -26
  7. package/dist/chrome.mjs.map +1 -1
  8. package/dist/code.d.mts +52 -0
  9. package/dist/code.d.ts +52 -0
  10. package/dist/code.js +534 -0
  11. package/dist/code.js.map +1 -0
  12. package/dist/code.mjs +522 -0
  13. package/dist/code.mjs.map +1 -0
  14. package/dist/components.d.mts +61 -117
  15. package/dist/components.d.ts +61 -117
  16. package/dist/components.js +2178 -106
  17. package/dist/components.js.map +1 -1
  18. package/dist/components.mjs +2150 -110
  19. package/dist/components.mjs.map +1 -1
  20. package/dist/docs-DhnstueM.d.ts +219 -0
  21. package/dist/docs-DiR6s43s.d.mts +219 -0
  22. package/dist/family.js +2 -1
  23. package/dist/family.js.map +1 -1
  24. package/dist/family.mjs +2 -1
  25. package/dist/family.mjs.map +1 -1
  26. package/dist/format.d.mts +12 -0
  27. package/dist/format.d.ts +12 -0
  28. package/dist/format.js +65 -0
  29. package/dist/format.js.map +1 -0
  30. package/dist/format.mjs +58 -0
  31. package/dist/format.mjs.map +1 -0
  32. package/dist/hero-Dn37il-9.d.mts +31 -0
  33. package/dist/hero-Dn37il-9.d.ts +31 -0
  34. package/dist/index.d.mts +10 -3
  35. package/dist/index.d.ts +10 -3
  36. package/dist/index.js +2675 -131
  37. package/dist/index.js.map +1 -1
  38. package/dist/index.mjs +2621 -134
  39. package/dist/index.mjs.map +1 -1
  40. package/dist/mdx.d.mts +58 -0
  41. package/dist/mdx.d.ts +58 -0
  42. package/dist/mdx.js +1719 -0
  43. package/dist/mdx.js.map +1 -0
  44. package/dist/mdx.mjs +1692 -0
  45. package/dist/mdx.mjs.map +1 -0
  46. package/dist/primitives.d.mts +22 -5
  47. package/dist/primitives.d.ts +22 -5
  48. package/dist/primitives.js +51 -5
  49. package/dist/primitives.js.map +1 -1
  50. package/dist/primitives.mjs +51 -7
  51. package/dist/primitives.mjs.map +1 -1
  52. package/dist/session.d.mts +18 -0
  53. package/dist/session.d.ts +18 -0
  54. package/dist/session.js +432 -0
  55. package/dist/session.js.map +1 -0
  56. package/dist/session.mjs +401 -0
  57. package/dist/session.mjs.map +1 -0
  58. package/dist/styles/code.css +97 -0
  59. package/dist/styles/theme.css +2 -0
  60. package/dist/styles/tokens.css +40 -0
  61. package/dist/styles.css +1 -0
  62. package/dist/tool-shell-B1C7ahKE.d.ts +81 -0
  63. package/dist/tool-shell-BDx_N5ai.d.mts +81 -0
  64. package/dist/tools-BggNN5DV.d.ts +131 -0
  65. package/dist/tools-DFIxIj5p.d.mts +131 -0
  66. package/package.json +31 -2
package/dist/chrome.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { X, ChevronDown, Menu, ChevronRight, Sun, Moon, SunMoon } from 'lucide-react';
2
- import Link3 from 'next/link';
3
- import { forwardRef, createContext, useState, useContext, useMemo, useEffect, useId, useRef } from 'react';
1
+ import { X, ChevronDown, Menu, ChevronRight, PanelLeft, Sun, Moon, SunMoon, CircleUser, LogOut, ArrowUpRight } from 'lucide-react';
2
+ import Link5 from 'next/link';
3
+ import { forwardRef, createContext, useState, useContext, useMemo, useEffect, useRef, useId, createElement } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { extendTailwindMerge } from 'tailwind-merge';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -9,6 +9,9 @@ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
9
9
  import * as PopoverPrimitive from '@radix-ui/react-popover';
10
10
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
11
11
  import { cva } from 'class-variance-authority';
12
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
13
+ import 'sonner';
14
+ import { Slot } from '@radix-ui/react-slot';
12
15
  import { useTheme } from 'next-themes';
13
16
 
14
17
  var merge = extendTailwindMerge({
@@ -179,7 +182,8 @@ var FAMILY = [
179
182
  group: "app",
180
183
  line: "Builders find co-founders and backers.",
181
184
  status: "testing",
182
- protocols: ["attest"]
185
+ // Signs in with an orangecheck account and a wallet; uses none of the six directly.
186
+ protocols: []
183
187
  },
184
188
  {
185
189
  slug: "me-demo",
@@ -213,7 +217,10 @@ var FAMILY_GROUPS = [
213
217
  { id: "app", label: "Apps" },
214
218
  { id: "public-good", label: "Public goods" }
215
219
  ];
216
- new Map(FAMILY.map((s) => [s.slug, s]));
220
+ var BY_SLUG = new Map(FAMILY.map((s) => [s.slug, s]));
221
+ function protocolSite(slug) {
222
+ return BY_SLUG.get(slug);
223
+ }
217
224
  function familyByGroup() {
218
225
  return FAMILY_GROUPS.map((g) => ({ ...g, sites: FAMILY.filter((s) => s.group === g.id) }));
219
226
  }
@@ -224,7 +231,7 @@ var LEGAL_LINKS = [
224
231
  { href: `${OCHK_IO}/trademark`, label: "Trademarks" },
225
232
  { href: `${OCHK_IO}/contact`, label: "Contact" }
226
233
  ];
227
- [
234
+ var OCHK_IO_NAV = [
228
235
  {
229
236
  href: `${OCHK_IO}/protocols`,
230
237
  label: "Protocols",
@@ -235,6 +242,16 @@ var LEGAL_LINKS = [
235
242
  { href: `${OCHK_IO}/trust`, label: "Trust" },
236
243
  { href: `${OCHK_IO}/about`, label: "About" }
237
244
  ];
245
+ var OCHK_IO_FOOTER = [
246
+ {
247
+ heading: "Company",
248
+ links: [
249
+ { href: `${OCHK_IO}/about`, label: "About" },
250
+ { href: `${OCHK_IO}/trust`, label: "Trust" },
251
+ { href: "https://github.com/orangecheck", label: "GitHub", external: true }
252
+ ]
253
+ }
254
+ ];
238
255
  var overlayClass = "oca-animate-fade fixed inset-0 z-50 bg-[rgb(10_10_10/0.38)] backdrop-blur-[2px] data-[state=closed]:opacity-0";
239
256
  forwardRef(function DialogContent2({ className, children, hideClose, ...props }, ref) {
240
257
  return /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
@@ -515,16 +532,23 @@ function FamilyMenu({ current, className }) {
515
532
  )
516
533
  ] });
517
534
  }
518
- function NavLink({ item, className, onNavigate }) {
535
+ function NavLink({
536
+ item,
537
+ className,
538
+ onNavigate,
539
+ line = false
540
+ }) {
519
541
  const cls = cn(
520
542
  "rounded-full px-3 py-2 text-[0.9375rem] transition-colors",
521
543
  item.active ? "text-foreground" : "text-muted-foreground hover:text-foreground",
544
+ line && "relative after:absolute after:inset-x-3 after:-bottom-[0.625rem] after:h-0.5 after:rounded-full",
545
+ line && item.active && "after:bg-foreground",
522
546
  className
523
547
  );
524
548
  if (item.external) {
525
549
  return /* @__PURE__ */ jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: item.label });
526
550
  }
527
- return /* @__PURE__ */ jsx(Link3, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: item.label });
551
+ return /* @__PURE__ */ jsx(Link5, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: item.label });
528
552
  }
529
553
  function NavRow({ item, onNavigate }) {
530
554
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -535,7 +559,7 @@ function NavRow({ item, onNavigate }) {
535
559
  "flex flex-col gap-0.5 rounded-xl px-3 py-2 transition-colors hover:bg-accent",
536
560
  item.active && "bg-muted hover:bg-muted dark:bg-white/[0.06]"
537
561
  );
538
- return item.external ? /* @__PURE__ */ jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: body }) : /* @__PURE__ */ jsx(Link3, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: body });
562
+ return item.external ? /* @__PURE__ */ jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: body }) : /* @__PURE__ */ jsx(Link5, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: body });
539
563
  }
540
564
  var seeAll = (item) => typeof item.label === "string" ? `All ${item.label.toLowerCase()}` : "See all";
541
565
  function NavDropdown({ item }) {
@@ -577,13 +601,16 @@ function SiteHeader({
577
601
  search,
578
602
  actions,
579
603
  variant = "site",
604
+ navOnPhone = true,
605
+ menu: menuExtra,
580
606
  className
581
607
  }) {
582
608
  const [open, setOpen] = useState(false);
583
609
  const tool = variant === "tool";
584
610
  const size = tool ? 24 : 28;
585
611
  const current = typeof family === "string" ? family : void 0;
586
- const menu = nav.length > 0 || Boolean(family);
612
+ const phoneNav = navOnPhone ? nav : [];
613
+ const menu = phoneNav.length > 0 || Boolean(family) || Boolean(menuExtra);
587
614
  const brandNode = brand ?? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center", children: [
588
615
  /* @__PURE__ */ jsx(Lockup, { size }),
589
616
  product ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -591,7 +618,9 @@ function SiteHeader({
591
618
  /* @__PURE__ */ jsx("span", { className: "font-medium tracking-[-0.01em]", style: { fontSize: size * 0.56 }, children: product })
592
619
  ] }) : null
593
620
  ] });
594
- const navigation = nav.length > 0 ? /* @__PURE__ */ jsx("nav", { "aria-label": "Main", className: "hidden items-center gap-1 md:flex", children: nav.map((n) => n.children?.length ? /* @__PURE__ */ jsx(NavDropdown, { item: n }, n.href) : /* @__PURE__ */ jsx(NavLink, { item: n }, n.href)) }) : null;
621
+ const navigation = nav.length > 0 ? /* @__PURE__ */ jsx("nav", { "aria-label": "Main", className: "hidden items-center gap-1 md:flex", children: nav.map(
622
+ (n) => n.children?.length ? /* @__PURE__ */ jsx(NavDropdown, { item: n }, n.href) : /* @__PURE__ */ jsx(NavLink, { item: n, line: tool }, n.href)
623
+ ) }) : null;
595
624
  return /* @__PURE__ */ jsx(
596
625
  "header",
597
626
  {
@@ -613,7 +642,7 @@ function SiteHeader({
613
642
  ),
614
643
  children: [
615
644
  /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-center gap-1", tool ? "md:gap-1" : "justify-self-start"), children: [
616
- /* @__PURE__ */ jsxs(Link3, { href: home, className: "-ml-1 min-w-0 rounded-lg p-1", children: [
645
+ /* @__PURE__ */ jsxs(Link5, { href: home, className: "-ml-1 min-w-0 rounded-lg p-1", children: [
617
646
  brandNode,
618
647
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: " home" })
619
648
  ] }),
@@ -635,7 +664,8 @@ function SiteHeader({
635
664
  ),
636
665
  /* @__PURE__ */ jsxs(SheetContent, { side: "right", className: "pt-16", children: [
637
666
  /* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Menu" }),
638
- nav.length > 0 ? /* @__PURE__ */ jsx("nav", { "aria-label": "Main", className: "flex flex-col", children: nav.map(
667
+ menuExtra ? /* @__PURE__ */ jsx("div", { className: cn("flex flex-col", (phoneNav.length > 0 || family) && "border-b border-border pb-3"), children: menuExtra }) : null,
668
+ phoneNav.length > 0 ? /* @__PURE__ */ jsx("nav", { "aria-label": "Main", className: "flex flex-col", children: phoneNav.map(
639
669
  (n) => n.children?.length ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col py-2", children: [
640
670
  /* @__PURE__ */ jsx("p", { className: "px-3 pb-1 text-[0.8125rem] text-muted-foreground", children: n.label }),
641
671
  n.children.map((c) => /* @__PURE__ */ jsx(
@@ -657,7 +687,7 @@ function SiteHeader({
657
687
  n.href
658
688
  )
659
689
  ) }) : null,
660
- family ? /* @__PURE__ */ jsxs("details", { className: cn("group", nav.length > 0 && "mt-2 border-t border-border pt-4"), children: [
690
+ family ? /* @__PURE__ */ jsxs("details", { className: cn("group", phoneNav.length > 0 && "mt-2 border-t border-border pt-4"), children: [
661
691
  /* @__PURE__ */ jsxs("summary", { className: "flex cursor-pointer list-none items-center justify-between rounded-xl px-3 py-2.5 text-[1.0625rem] [&::-webkit-details-marker]:hidden", children: [
662
692
  "All orangecheck sites",
663
693
  /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-open:rotate-180" })
@@ -888,12 +918,12 @@ function SignInFrame({
888
918
  children: [
889
919
  /* @__PURE__ */ jsxs("section", { className: "flex flex-col px-4 pb-8 pt-5 sm:px-8 lg:px-14 lg:pt-8", children: [
890
920
  /* @__PURE__ */ jsxs("header", { className: "flex items-center justify-between gap-4", children: [
891
- /* @__PURE__ */ jsxs(Link3, { href: home, className: "w-fit rounded-lg", children: [
921
+ /* @__PURE__ */ jsxs(Link5, { href: home, className: "w-fit rounded-lg", children: [
892
922
  brand ?? /* @__PURE__ */ jsx(Lockup, { size: 28 }),
893
923
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: " home" })
894
924
  ] }),
895
925
  back === void 0 ? /* @__PURE__ */ jsx(
896
- Link3,
926
+ Link5,
897
927
  {
898
928
  href: home,
899
929
  className: "text-[0.9375rem] text-muted-foreground underline-offset-4 hover:text-foreground hover:underline",
@@ -926,15 +956,335 @@ function SignInFrame({
926
956
  }
927
957
  );
928
958
  }
929
- var ShellContext = createContext({});
959
+ function Spinner({ className, label }) {
960
+ return /* @__PURE__ */ jsxs(
961
+ "svg",
962
+ {
963
+ viewBox: "0 0 24 24",
964
+ fill: "none",
965
+ role: label ? "status" : void 0,
966
+ "aria-label": label,
967
+ "aria-hidden": label ? void 0 : true,
968
+ className: cn("size-4 animate-spin", className),
969
+ children: [
970
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9", stroke: "currentColor", strokeOpacity: "0.2", strokeWidth: "2.5" }),
971
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 0 0-9-9", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" })
972
+ ]
973
+ }
974
+ );
975
+ }
976
+ forwardRef(function Separator3({ className, orientation = "horizontal", decorative = true, ...props }, ref) {
977
+ return /* @__PURE__ */ jsx(
978
+ SeparatorPrimitive.Root,
979
+ {
980
+ ref,
981
+ decorative,
982
+ orientation,
983
+ className: cn(
984
+ "shrink-0 bg-border",
985
+ orientation === "horizontal" ? "h-px w-full" : "h-full w-px",
986
+ className
987
+ ),
988
+ ...props
989
+ }
990
+ );
991
+ });
992
+ function sharedContext(name, initial) {
993
+ const key = /* @__PURE__ */ Symbol.for(`@orangecheck/app-design/${name}`);
994
+ const store = globalThis;
995
+ return store[key] ?? (store[key] = createContext(initial));
996
+ }
997
+
998
+ // src/lib/density.ts
999
+ var DensityContext = sharedContext("density", "comfortable");
1000
+ function DensityProvider({ density, children }) {
1001
+ return createElement(DensityContext.Provider, { value: density }, children);
1002
+ }
1003
+ var ShellContext = sharedContext("shell-place", {});
930
1004
  function useShellPlace() {
931
1005
  return useContext(ShellContext);
932
1006
  }
1007
+ var buttonVariants = cva(
1008
+ [
1009
+ "inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-full font-medium",
1010
+ "transition-[background-color,border-color,color,box-shadow,transform] duration-150",
1011
+ "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1012
+ "active:translate-y-px disabled:pointer-events-none",
1013
+ // Disabled is one look for every variant: a quiet grey pill, never a
1014
+ // faded black or orange slab that reads as broken.
1015
+ "disabled:border disabled:border-border disabled:bg-muted disabled:text-oca-subtle disabled:shadow-none",
1016
+ "[&_svg]:pointer-events-none [&_svg]:size-[1.1em] [&_svg]:shrink-0"
1017
+ ],
1018
+ {
1019
+ variants: {
1020
+ variant: {
1021
+ primary: "bg-primary text-primary-foreground hover:bg-primary/85",
1022
+ secondary: "border border-border bg-secondary text-secondary-foreground hover:border-oca-hairline-strong hover:bg-accent",
1023
+ brand: "bg-brand text-brand-foreground hover:bg-oca-orange-deep",
1024
+ ghost: "text-foreground hover:bg-accent",
1025
+ danger: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
1026
+ link: "h-auto rounded-none px-0 text-foreground underline decoration-foreground/35 underline-offset-4 hover:decoration-foreground",
1027
+ onInk: "bg-white text-oca-ink hover:bg-white/90",
1028
+ onInkOutline: "border border-white/20 text-white hover:bg-white/10"
1029
+ },
1030
+ size: {
1031
+ sm: "h-9 px-4 text-sm",
1032
+ md: "h-11 px-5 text-[0.9375rem]",
1033
+ lg: "h-14 px-7 text-[1.0625rem]",
1034
+ icon: "size-10",
1035
+ "icon-sm": "size-8"
1036
+ }
1037
+ },
1038
+ compoundVariants: [{ variant: "link", className: "h-auto px-0" }],
1039
+ defaultVariants: { variant: "primary", size: "md" }
1040
+ }
1041
+ );
1042
+ var Button = forwardRef(function Button2({ className, variant, size, asChild = false, loading = false, disabled, children, type, ...props }, ref) {
1043
+ const Comp = asChild ? Slot : "button";
1044
+ return /* @__PURE__ */ jsx(
1045
+ Comp,
1046
+ {
1047
+ ref,
1048
+ "data-ui": "button",
1049
+ className: cn(buttonVariants({ variant, size }), className),
1050
+ disabled: asChild ? void 0 : disabled || loading,
1051
+ "aria-busy": loading || void 0,
1052
+ type: asChild ? void 0 : type ?? "button",
1053
+ ...props,
1054
+ children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1055
+ loading ? /* @__PURE__ */ jsx(Spinner, { className: "size-[1.1em]" }) : null,
1056
+ children
1057
+ ] })
1058
+ }
1059
+ );
1060
+ });
1061
+ function useActiveHeading(ids) {
1062
+ const [active, setActive] = useState(ids[0]);
1063
+ const key = ids.join("|");
1064
+ useEffect(() => {
1065
+ setActive(key.split("|")[0] || void 0);
1066
+ const els = key.split("|").map((id) => document.getElementById(id)).filter((el) => el !== null);
1067
+ if (els.length === 0 || typeof IntersectionObserver === "undefined") return;
1068
+ const io = new IntersectionObserver(
1069
+ (entries) => {
1070
+ const hit = entries.filter((e) => e.isIntersecting).sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top)[0];
1071
+ if (hit) setActive(hit.target.id);
1072
+ },
1073
+ { rootMargin: "-80px 0px -65% 0px" }
1074
+ );
1075
+ els.forEach((el) => io.observe(el));
1076
+ return () => io.disconnect();
1077
+ }, [key]);
1078
+ return active;
1079
+ }
1080
+ function useHeadings(selector = "#docs-content", key) {
1081
+ const [items, setItems] = useState([]);
1082
+ useEffect(() => {
1083
+ const read = () => {
1084
+ const root = document.querySelector(selector);
1085
+ if (!root) return setItems([]);
1086
+ setItems(
1087
+ Array.from(root.querySelectorAll("h2[id], h3[id]")).map((h) => ({
1088
+ id: h.id,
1089
+ // The anchor link's "#" is not part of the name.
1090
+ label: (h.querySelector("[data-heading-text]") ?? h).textContent?.trim() ?? "",
1091
+ level: h.tagName === "H3" ? 3 : 2
1092
+ }))
1093
+ );
1094
+ };
1095
+ const raf = requestAnimationFrame(read);
1096
+ const t = setTimeout(read, 80);
1097
+ return () => {
1098
+ cancelAnimationFrame(raf);
1099
+ clearTimeout(t);
1100
+ };
1101
+ }, [selector, key]);
1102
+ const activeId = useActiveHeading(items.map((i) => i.id));
1103
+ return { items, activeId };
1104
+ }
1105
+ function OnThisPage({
1106
+ items,
1107
+ activeId,
1108
+ title = "On this page",
1109
+ onNavigate,
1110
+ className
1111
+ }) {
1112
+ const id = useId();
1113
+ if (items.length === 0) return null;
1114
+ return (
1115
+ // With no visible title (a folded list under its own summary) the name is still "On this page".
1116
+ /* @__PURE__ */ jsxs("nav", { "aria-labelledby": title ? id : void 0, "aria-label": title ? void 0 : "On this page", className, children: [
1117
+ title ? /* @__PURE__ */ jsx("p", { id, className: "mb-3 text-[0.875rem] font-medium", children: title }) : null,
1118
+ /* @__PURE__ */ jsx("ul", { children: items.map((t) => {
1119
+ const on = t.id === activeId;
1120
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
1121
+ "a",
1122
+ {
1123
+ href: `#${t.id}`,
1124
+ onClick: onNavigate,
1125
+ "aria-current": on ? "location" : void 0,
1126
+ className: cn(
1127
+ "block border-l py-1.5 text-[0.875rem] leading-snug transition-colors",
1128
+ t.level === 3 ? "pl-7" : "pl-4",
1129
+ on ? "border-foreground text-foreground" : "border-border text-muted-foreground hover:text-foreground"
1130
+ ),
1131
+ children: t.label
1132
+ }
1133
+ ) }, t.id);
1134
+ }) })
1135
+ ] })
1136
+ );
1137
+ }
1138
+ var STATUS_WORDS = /* @__PURE__ */ new Set(["live", "testing", "not-yet", "paused", "good", "caution", "refused"]);
1139
+ var pathOf = (href) => href.split(/[?#]/)[0].replace(/(.)\/$/, "$1");
1140
+ function DocsNav({
1141
+ sections,
1142
+ current,
1143
+ onNavigate,
1144
+ className
1145
+ }) {
1146
+ const here = pathOf(current);
1147
+ const activeSection = useMemo(
1148
+ () => sections.findIndex((s) => s.items.some((i) => pathOf(i.href) === here)),
1149
+ [sections, here]
1150
+ );
1151
+ const [peeked, setPeeked] = useState(() => /* @__PURE__ */ new Set());
1152
+ useEffect(() => setPeeked(/* @__PURE__ */ new Set()), [activeSection]);
1153
+ const activeRef = useRef(null);
1154
+ useEffect(() => {
1155
+ const id = requestAnimationFrame(() => activeRef.current?.scrollIntoView({ block: "nearest" }));
1156
+ return () => cancelAnimationFrame(id);
1157
+ }, [here]);
1158
+ const base = useId();
1159
+ return /* @__PURE__ */ jsx("nav", { "aria-label": "Docs", className: cn("flex flex-col gap-0.5", className), children: sections.map((section, si) => {
1160
+ const isActive = si === activeSection;
1161
+ const open = isActive || peeked.has(si);
1162
+ const panel = `${base}-s${si}`;
1163
+ return /* @__PURE__ */ jsxs("div", { children: [
1164
+ /* @__PURE__ */ jsxs(
1165
+ "button",
1166
+ {
1167
+ type: "button",
1168
+ "aria-expanded": open,
1169
+ "aria-controls": panel,
1170
+ onClick: () => {
1171
+ if (isActive) return;
1172
+ setPeeked((p) => {
1173
+ const n = new Set(p);
1174
+ if (n.has(si)) n.delete(si);
1175
+ else n.add(si);
1176
+ return n;
1177
+ });
1178
+ },
1179
+ className: cn(
1180
+ "flex min-h-9 w-full items-center justify-between gap-2 rounded-lg px-2.5 py-1.5 text-left text-[0.875rem] transition-colors",
1181
+ isActive ? "font-medium text-foreground" : "text-muted-foreground hover:bg-accent hover:text-foreground",
1182
+ isActive && "cursor-default"
1183
+ ),
1184
+ children: [
1185
+ section.label,
1186
+ /* @__PURE__ */ jsx(
1187
+ ChevronRight,
1188
+ {
1189
+ "aria-hidden": true,
1190
+ className: cn("size-3.5 shrink-0 text-oca-subtle transition-transform duration-200", open && "rotate-90")
1191
+ }
1192
+ )
1193
+ ]
1194
+ }
1195
+ ),
1196
+ /* @__PURE__ */ jsx("ul", { id: panel, hidden: !open, className: "mb-2 ml-2.5 mt-0.5 border-l border-border", children: section.items.map((item) => {
1197
+ const on = pathOf(item.href) === here;
1198
+ const badge = typeof item.badge === "string" && STATUS_WORDS.has(item.badge) ? /* @__PURE__ */ jsx(StatusBadge, { status: item.badge }) : item.badge ? /* @__PURE__ */ jsx(Badge, { tone: "muted", children: item.badge }) : null;
1199
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
1200
+ Link5,
1201
+ {
1202
+ href: item.href,
1203
+ ref: on ? activeRef : void 0,
1204
+ onClick: onNavigate,
1205
+ "aria-current": on ? "page" : void 0,
1206
+ className: cn(
1207
+ "-ml-px flex min-h-9 items-center gap-2 border-l-2 py-1.5 pl-3.5 pr-2 text-[0.875rem] leading-snug transition-colors",
1208
+ on ? "border-foreground font-medium text-foreground" : "border-transparent text-muted-foreground hover:border-oca-hairline-strong hover:text-foreground"
1209
+ ),
1210
+ children: [
1211
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children: item.label }),
1212
+ badge
1213
+ ]
1214
+ }
1215
+ ) }, item.href);
1216
+ }) })
1217
+ ] }, section.label);
1218
+ }) });
1219
+ }
1220
+ var DOCS_HEADER_NAV = OCHK_IO_NAV.map((n) => n.href === DOCS_HREF ? { ...n, active: true } : n);
1221
+ function DocsShell({
1222
+ nav,
1223
+ current,
1224
+ header,
1225
+ search,
1226
+ actions,
1227
+ breadcrumbs,
1228
+ toc,
1229
+ pager,
1230
+ footer,
1231
+ children
1232
+ }) {
1233
+ const [menu, setMenu] = useState(false);
1234
+ useEffect(() => setMenu(false), [current]);
1235
+ const read = useHeadings("#docs-content", current);
1236
+ const items = toc ?? read.items;
1237
+ const activeId = toc ? void 0 : read.activeId;
1238
+ const here = pathOf(current);
1239
+ const place = useMemo(() => {
1240
+ for (const s of nav) {
1241
+ const it = s.items.find((i) => pathOf(i.href) === here);
1242
+ if (it) return { section: s.label, page: it.label };
1243
+ }
1244
+ return null;
1245
+ }, [nav, here]);
1246
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-h-dvh flex-col bg-background", children: [
1247
+ /* @__PURE__ */ jsx(SkipLink, {}),
1248
+ header ?? /* @__PURE__ */ jsx(SiteHeader, { home: OCHK_IO, family: "docs", nav: DOCS_HEADER_NAV, search, actions }),
1249
+ /* @__PURE__ */ jsx("div", { className: "sticky top-16 z-30 border-b border-border bg-background/95 backdrop-blur-md supports-[backdrop-filter]:bg-background/90 md:top-[4.5rem] lg:hidden", children: /* @__PURE__ */ jsx("div", { className: "oca-container flex h-12 items-center gap-2", children: /* @__PURE__ */ jsxs(Sheet, { open: menu, onOpenChange: setMenu, children: [
1250
+ /* @__PURE__ */ jsxs(SheetTrigger, { className: "-ml-2 inline-flex h-10 min-w-0 items-center gap-2 rounded-full px-2.5 text-[0.875rem] hover:bg-accent", children: [
1251
+ /* @__PURE__ */ jsx(PanelLeft, { "aria-hidden": true, className: "size-[1.125rem] shrink-0" }),
1252
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Docs menu. " }),
1253
+ place ? /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1254
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: place.section }),
1255
+ /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-oca-subtle" }),
1256
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: place.page })
1257
+ ] }) : /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Docs" })
1258
+ ] }),
1259
+ /* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "w-[min(88vw,22rem)] gap-0 p-0", children: [
1260
+ /* @__PURE__ */ jsx("div", { className: "border-b border-border px-5 py-4 pr-14", children: /* @__PURE__ */ jsx(SheetTitle, { className: "text-[1.0625rem] font-medium", children: "Docs" }) }),
1261
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto p-3", children: /* @__PURE__ */ jsx(DocsNav, { sections: nav, current, onNavigate: () => setMenu(false) }) })
1262
+ ] })
1263
+ ] }) }) }),
1264
+ /* @__PURE__ */ jsx("div", { className: "oca-container flex-1", children: /* @__PURE__ */ jsxs("div", { className: "lg:grid lg:grid-cols-[13.5rem_minmax(0,1fr)] lg:gap-x-10 xl:grid-cols-[13.5rem_minmax(0,1fr)_11rem]", children: [
1265
+ /* @__PURE__ */ jsx("div", { className: "sticky top-[4.5rem] hidden max-h-[calc(100dvh-4.5rem)] self-start overflow-y-auto overscroll-contain py-8 pr-1 lg:block", children: /* @__PURE__ */ jsx(DocsNav, { sections: nav, current }) }),
1266
+ /* @__PURE__ */ jsxs("main", { id: "main-content", className: "min-w-0 pb-16 pt-6 md:pt-8", children: [
1267
+ breadcrumbs ? /* @__PURE__ */ jsx("div", { className: "mb-6 max-lg:hidden", children: breadcrumbs }) : null,
1268
+ items.length > 1 ? /* @__PURE__ */ jsxs("details", { className: "group mb-8 rounded-2xl border border-border bg-card xl:hidden", children: [
1269
+ /* @__PURE__ */ jsxs("summary", { className: "flex min-h-12 cursor-pointer list-none items-center justify-between px-4 text-[0.9375rem] font-medium [&::-webkit-details-marker]:hidden", children: [
1270
+ "On this page",
1271
+ /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-open:rotate-180" })
1272
+ ] }),
1273
+ /* @__PURE__ */ jsx(OnThisPage, { items, activeId, title: null, className: "px-4 pb-4" })
1274
+ ] }) : null,
1275
+ /* @__PURE__ */ jsx("article", { id: "docs-content", className: "max-w-[46rem]", children }),
1276
+ pager ? /* @__PURE__ */ jsx("div", { className: "mt-16 max-w-[46rem]", children: pager }) : null
1277
+ ] }),
1278
+ /* @__PURE__ */ jsx("div", { className: "sticky top-[4.5rem] hidden max-h-[calc(100dvh-4.5rem)] self-start overflow-y-auto py-10 xl:block", children: items.length > 1 ? /* @__PURE__ */ jsx(OnThisPage, { items, activeId }) : null })
1279
+ ] }) }),
1280
+ footer ?? /* @__PURE__ */ jsx(SiteFooter, { columns: OCHK_IO_FOOTER, family: true, legal: true, signature: false })
1281
+ ] });
1282
+ }
933
1283
  function SideNav({ groups, onNavigate }) {
934
1284
  return /* @__PURE__ */ jsx("nav", { "aria-label": "Pages", className: "flex flex-col gap-5", children: groups.map((g, gi) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
935
1285
  g.label ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-1 text-[0.8125rem] text-muted-foreground", children: g.label }) : null,
936
1286
  g.items.map((it) => /* @__PURE__ */ jsxs(
937
- Link3,
1287
+ Link5,
938
1288
  {
939
1289
  href: it.href,
940
1290
  onClick: onNavigate,
@@ -969,7 +1319,7 @@ function SectionSwitch({
969
1319
  children: sections.map((sec) => {
970
1320
  const on = sec.id === current.id;
971
1321
  return /* @__PURE__ */ jsx(
972
- Link3,
1322
+ Link5,
973
1323
  {
974
1324
  href: sec.href,
975
1325
  onClick: onNavigate,
@@ -999,7 +1349,7 @@ function TabBar({ items }) {
999
1349
  className: "mx-auto grid h-14 max-w-[32rem] px-1.5",
1000
1350
  style: { gridTemplateColumns: `repeat(${items.length}, minmax(0, 1fr))` },
1001
1351
  children: items.map((it) => /* @__PURE__ */ jsxs(
1002
- Link3,
1352
+ Link5,
1003
1353
  {
1004
1354
  href: it.href,
1005
1355
  "aria-current": it.active ? "page" : void 0,
@@ -1108,7 +1458,7 @@ function AppShell({
1108
1458
  footer ? /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer }) : null
1109
1459
  ] })
1110
1460
  ] }),
1111
- /* @__PURE__ */ jsx(Link3, { href: home, "aria-label": "Home", className: "rounded-lg p-1", children: /* @__PURE__ */ jsx(Lockup, { size: 22 }) }),
1461
+ /* @__PURE__ */ jsx(Link5, { href: home, "aria-label": "Home", className: "rounded-lg p-1", children: /* @__PURE__ */ jsx(Lockup, { size: 22 }) }),
1112
1462
  /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center", children: account })
1113
1463
  ] }),
1114
1464
  place.page ? /* @__PURE__ */ jsxs(
@@ -1131,7 +1481,7 @@ function AppShell({
1131
1481
  ] }),
1132
1482
  /* @__PURE__ */ jsxs("div", { className: "mx-auto flex w-full max-w-[90rem]", children: [
1133
1483
  /* @__PURE__ */ jsxs("aside", { className: "sticky top-0 hidden h-dvh w-[17rem] shrink-0 flex-col gap-6 overflow-y-auto px-4 py-6 lg:flex", children: [
1134
- /* @__PURE__ */ jsx(Link3, { href: home, className: "px-2", "aria-label": "Home", children: /* @__PURE__ */ jsx(Lockup, { size: 26 }) }),
1484
+ /* @__PURE__ */ jsx(Link5, { href: home, className: "px-2", "aria-label": "Home", children: /* @__PURE__ */ jsx(Lockup, { size: 26 }) }),
1135
1485
  switcher,
1136
1486
  /* @__PURE__ */ jsx(SideNav, { groups }),
1137
1487
  /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer })
@@ -1162,9 +1512,16 @@ function AccountMenu({
1162
1512
  "inline-flex h-10 items-center gap-2.5 rounded-full border border-border bg-card pl-1 pr-1 text-[0.9375rem] outline-none transition-colors hover:border-oca-hairline-strong focus-visible:ring-2 focus-visible:ring-ring",
1163
1513
  nameFrom === "lg" ? "lg:pr-3.5" : "sm:pr-3.5"
1164
1514
  ),
1165
- "aria-label": `Account: ${name}`,
1515
+ "aria-label": `${name}, account menu`,
1166
1516
  children: [
1167
- /* @__PURE__ */ jsx("span", { className: "flex size-8 items-center justify-center rounded-full bg-foreground text-[0.8125rem] font-medium text-background", children: initial }),
1517
+ /* @__PURE__ */ jsx(
1518
+ "span",
1519
+ {
1520
+ "aria-hidden": true,
1521
+ "data-initial": initial,
1522
+ className: "flex size-8 items-center justify-center rounded-full bg-foreground text-[0.8125rem] font-medium text-background before:content-[attr(data-initial)]"
1523
+ }
1524
+ ),
1168
1525
  /* @__PURE__ */ jsx("span", { className: cn("max-w-[10rem] truncate", nameFrom === "lg" ? "max-lg:hidden" : "max-sm:hidden"), children: name })
1169
1526
  ]
1170
1527
  }
@@ -1176,7 +1533,7 @@ function AccountMenu({
1176
1533
  ] }),
1177
1534
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
1178
1535
  items.map(
1179
- (it, i) => it === "separator" ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}, `sep-${i}`) : it.href ? /* @__PURE__ */ jsx(DropdownMenuItem, { asChild: true, destructive: it.destructive, children: /* @__PURE__ */ jsxs(Link3, { href: it.href, children: [
1536
+ (it, i) => it === "separator" ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}, `sep-${i}`) : it.href ? /* @__PURE__ */ jsx(DropdownMenuItem, { asChild: true, destructive: it.destructive, children: /* @__PURE__ */ jsxs(Link5, { href: it.href, children: [
1180
1537
  it.icon,
1181
1538
  it.label
1182
1539
  ] }) }, it.label) : /* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: it.onSelect, destructive: it.destructive, children: [
@@ -1209,7 +1566,121 @@ function ThemeToggle({ className }) {
1209
1566
  }
1210
1567
  );
1211
1568
  }
1569
+ var OCHK_APP_ACCOUNT = "https://ochk.app/me/account";
1570
+ function SessionAccountView({
1571
+ state,
1572
+ name,
1573
+ detail,
1574
+ items = [],
1575
+ signInHref,
1576
+ signInLabel = "Sign in",
1577
+ accountHref = OCHK_APP_ACCOUNT,
1578
+ onSignOut,
1579
+ nameFrom = "lg"
1580
+ }) {
1581
+ if (state === "in") {
1582
+ return /* @__PURE__ */ jsx(
1583
+ AccountMenu,
1584
+ {
1585
+ name: name || "Your account",
1586
+ detail,
1587
+ nameFrom,
1588
+ items: [
1589
+ ...items,
1590
+ ...items.length > 0 ? ["separator"] : [],
1591
+ { label: "Your account", href: accountHref, icon: /* @__PURE__ */ jsx(CircleUser, {}) },
1592
+ "separator",
1593
+ { label: "Sign out", onSelect: onSignOut, icon: /* @__PURE__ */ jsx(LogOut, {}) }
1594
+ ]
1595
+ }
1596
+ );
1597
+ }
1598
+ if (state === "unknown") {
1599
+ return /* @__PURE__ */ jsx(Button, { asChild: true, size: "sm", variant: "secondary", children: /* @__PURE__ */ jsx("a", { href: accountHref, children: "Your account" }) });
1600
+ }
1601
+ return (
1602
+ // No box of its own: it sits exactly where the signed-in chip will. While checking it is only unseen.
1603
+ /* @__PURE__ */ jsx("span", { className: state === "checking" ? "contents invisible" : "contents", "aria-hidden": state === "checking" || void 0, children: /* @__PURE__ */ jsx(Button, { asChild: true, size: "sm", variant: "secondary", tabIndex: state === "checking" ? -1 : void 0, children: /* @__PURE__ */ jsx("a", { href: signInHref, children: signInLabel }) }) })
1604
+ );
1605
+ }
1606
+ function ToolShell({
1607
+ protocol: protocol2,
1608
+ tools,
1609
+ home = "/",
1610
+ account,
1611
+ rail = false,
1612
+ railFooter,
1613
+ variant = "tool",
1614
+ banner,
1615
+ footer,
1616
+ children
1617
+ }) {
1618
+ const p = protocolSite(protocol2);
1619
+ const app = variant === "app";
1620
+ const tabs = app ? null : tabsFor([{ items: [...tools] }]);
1621
+ const about = /* @__PURE__ */ jsxs(
1622
+ "a",
1623
+ {
1624
+ href: p.pageHref,
1625
+ className: "inline-flex items-center gap-1 rounded-full px-3 py-2 text-[0.9375rem] text-muted-foreground transition-colors hover:text-foreground",
1626
+ children: [
1627
+ "About ",
1628
+ p.label,
1629
+ /* @__PURE__ */ jsx(ArrowUpRight, { "aria-hidden": true, className: "size-3.5" })
1630
+ ]
1631
+ }
1632
+ );
1633
+ return /* @__PURE__ */ jsx(DensityProvider, { density: "compact", children: /* @__PURE__ */ jsxs(
1634
+ "div",
1635
+ {
1636
+ className: cn(
1637
+ "flex flex-col bg-background",
1638
+ app ? "h-dvh overflow-hidden" : "min-h-dvh",
1639
+ tabs && "max-md:pb-[calc(3.5rem_+_env(safe-area-inset-bottom))]"
1640
+ ),
1641
+ children: [
1642
+ /* @__PURE__ */ jsx(SkipLink, {}),
1643
+ banner,
1644
+ /* @__PURE__ */ jsx(
1645
+ SiteHeader,
1646
+ {
1647
+ variant: "tool",
1648
+ home,
1649
+ product: p.label,
1650
+ family: protocol2,
1651
+ nav: tools.map((t) => ({ href: t.href, label: t.label, active: t.active })),
1652
+ navOnPhone: !tabs,
1653
+ menu: /* @__PURE__ */ jsx("div", { className: "[&>a]:px-3 [&>a]:py-3 [&>a]:text-[1.0625rem]", children: about }),
1654
+ className: cn(rail && "lg:[&_nav[aria-label=Main]]:hidden"),
1655
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [
1656
+ /* @__PURE__ */ jsx("span", { className: "hidden lg:contents", children: about }),
1657
+ p.status !== "live" ? /* @__PURE__ */ jsx(StatusBadge, { status: p.status, className: "max-sm:hidden" }) : null,
1658
+ /* @__PURE__ */ jsx(ThemeToggle, { className: "max-sm:hidden" }),
1659
+ account
1660
+ ] })
1661
+ }
1662
+ ),
1663
+ /* @__PURE__ */ jsxs("div", { className: cn("mx-auto flex w-full", app ? "min-h-0 flex-1" : "max-w-[90rem] flex-1"), children: [
1664
+ rail ? /* @__PURE__ */ jsxs("aside", { className: "sticky top-14 hidden h-[calc(100dvh-3.5rem)] w-60 shrink-0 flex-col gap-6 overflow-y-auto px-4 py-6 lg:flex", children: [
1665
+ /* @__PURE__ */ jsx(SideNav, { groups: [{ label: "Tools", items: tools.map(({ href, label, icon, active }) => ({ href, label, icon, active })) }] }),
1666
+ railFooter ? /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col gap-0.5 px-3 text-[0.875rem] text-muted-foreground [&_a:hover]:text-foreground [&_a]:py-1.5 [&_a]:transition-colors", children: railFooter }) : null
1667
+ ] }) : null,
1668
+ /* @__PURE__ */ jsx(
1669
+ "main",
1670
+ {
1671
+ id: "main-content",
1672
+ className: cn("min-w-0 flex-1", app ? "flex min-h-0 flex-col" : "px-4 pb-16 pt-8 md:px-8 md:pt-10"),
1673
+ children: app ? children : /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-[72rem]", children })
1674
+ }
1675
+ )
1676
+ ] }),
1677
+ app || footer === false ? null : footer ?? /* @__PURE__ */ jsx(SiteFooter, { compact: true, family: true, legal: true }),
1678
+ tabs ? /* @__PURE__ */ jsx(TabBar, { items: tabs }) : null
1679
+ ]
1680
+ }
1681
+ ) });
1682
+ }
1212
1683
 
1213
- export { AccountMenu, AppShell, FamilyMenu, ShellContext, SignInFrame, SiteBanner, SiteFooter, SiteHeader, SkipLink, ThemeToggle, useShellPlace };
1684
+ export { AccountMenu, AppShell, DOCS_HEADER_NAV, DocsNav, DocsShell, FamilyMenu, OCHK_APP_ACCOUNT, SessionAccountView, ShellContext, SignInFrame, SiteBanner, SiteFooter, SiteHeader, SkipLink, ThemeToggle, ToolShell, useShellPlace };
1214
1685
  //# sourceMappingURL=chrome.mjs.map
1215
1686
  //# sourceMappingURL=chrome.mjs.map