@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
package/dist/chrome.mjs CHANGED
@@ -1,6 +1,6 @@
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';
1
+ import { X, ChevronDown, Menu, ChevronRight, Sun, Moon, SunMoon, PanelLeft, CircleUser, LogOut, ArrowUpRight } from 'lucide-react';
2
+ import Link from 'next/link';
3
+ import { forwardRef, createContext, useContext, useState, useMemo, useEffect, useRef, useId, useSyncExternalStore, 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';
@@ -8,11 +8,12 @@ import * as DialogPrimitive from '@radix-ui/react-dialog';
8
8
  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
+ import { useTheme } from 'next-themes';
11
12
  import { cva } from 'class-variance-authority';
12
13
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
13
14
  import 'sonner';
14
15
  import { Slot } from '@radix-ui/react-slot';
15
- import { useTheme } from 'next-themes';
16
+ import { useRouter } from 'next/compat/router';
16
17
 
17
18
  var merge = extendTailwindMerge({
18
19
  extend: {
@@ -406,6 +407,17 @@ var DropdownMenuLabel = forwardRef(function DropdownMenuLabel2({ className, ...p
406
407
  var DropdownMenuSeparator = forwardRef(function DropdownMenuSeparator2({ className, ...props }, ref) {
407
408
  return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Separator, { ref, className: cn("my-1.5 h-px bg-border", className), ...props });
408
409
  });
410
+ function sharedContext(name, initial) {
411
+ const key = /* @__PURE__ */ Symbol.for(`@orangecheck/app-design/${name}`);
412
+ const store = globalThis;
413
+ return store[key] ?? (store[key] = createContext(initial));
414
+ }
415
+
416
+ // src/lib/shell-context.ts
417
+ var ShellContext = sharedContext("shell-place", {});
418
+ function useShellPlace() {
419
+ return useContext(ShellContext);
420
+ }
409
421
  var GOOD_DOT = "border-border bg-card text-foreground before:size-1.5 before:shrink-0 before:rounded-full before:bg-success before:content-['']";
410
422
  var badgeVariants = cva(
411
423
  "inline-flex h-6 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 text-[0.8125rem] font-medium leading-none",
@@ -532,191 +544,483 @@ function FamilyMenu({ current, className }) {
532
544
  )
533
545
  ] });
534
546
  }
535
- function NavLink({
536
- item,
537
- className,
538
- onNavigate,
539
- line = false
540
- }) {
541
- const cls = cn(
542
- "rounded-full px-3 py-2 text-[0.9375rem] transition-colors",
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",
546
- className
547
- );
548
- if (item.external) {
549
- return /* @__PURE__ */ jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: item.label });
550
- }
551
- return /* @__PURE__ */ jsx(Link5, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: item.label });
552
- }
553
- function NavRow({ item, onNavigate }) {
554
- const body = /* @__PURE__ */ jsxs(Fragment, { children: [
555
- /* @__PURE__ */ jsx("span", { className: "text-[0.9375rem] font-medium leading-6 text-foreground", children: item.label }),
556
- item.description ? /* @__PURE__ */ jsx("span", { className: "text-[0.8125rem] leading-snug text-muted-foreground", children: item.description }) : null
557
- ] });
558
- const cls = cn(
559
- "flex flex-col gap-0.5 rounded-xl px-3 py-2 transition-colors hover:bg-accent",
560
- item.active && "bg-muted hover:bg-muted dark:bg-white/[0.06]"
561
- );
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 });
563
- }
564
- var seeAll = (item) => typeof item.label === "string" ? `All ${item.label.toLowerCase()}` : "See all";
565
- function NavDropdown({ item }) {
566
- const [open, setOpen] = useState(false);
567
- const active = item.active || item.children?.some((c) => c.active);
568
- return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
569
- /* @__PURE__ */ jsxs(
570
- PopoverTrigger,
547
+ function SideNav({ groups, onNavigate }) {
548
+ 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: [
549
+ g.label ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-1 text-[0.8125rem] text-muted-foreground", children: g.label }) : null,
550
+ g.items.map((it) => /* @__PURE__ */ jsxs(
551
+ Link,
571
552
  {
553
+ href: it.href,
554
+ onClick: onNavigate,
555
+ "aria-current": it.active ? "page" : void 0,
572
556
  className: cn(
573
- "group inline-flex items-center gap-1 rounded-full py-2 pl-3 pr-2.5 text-[0.9375rem] transition-colors md:max-lg:pl-2.5 md:max-lg:pr-2",
574
- active ? "text-foreground" : "text-muted-foreground hover:text-foreground data-[state=open]:text-foreground"
557
+ "flex h-9 items-center gap-3 rounded-xl px-3 text-[0.9375rem] transition-colors",
558
+ "[&_svg]:size-[1.0625rem] [&_svg]:shrink-0",
559
+ it.active ? "bg-card text-foreground shadow-sm ring-1 ring-border [&_svg]:text-foreground" : "text-muted-foreground hover:bg-accent hover:text-foreground"
575
560
  ),
576
561
  children: [
577
- item.label,
578
- /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-3.5 transition-transform duration-200 group-data-[state=open]:rotate-180" })
562
+ it.icon,
563
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: it.label }),
564
+ it.badge ? /* @__PURE__ */ jsx("span", { className: "shrink-0", children: it.badge }) : null
579
565
  ]
580
- }
581
- ),
582
- /* @__PURE__ */ jsxs(PopoverContent, { align: "center", sideOffset: 10, className: "w-[min(calc(100vw-2rem),26rem)] p-2", children: [
583
- /* @__PURE__ */ jsx("ul", { className: "flex flex-col", children: item.children?.map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(NavRow, { item: c, onNavigate: () => setOpen(false) }) }, c.href)) }),
584
- /* @__PURE__ */ jsx("div", { className: "mt-1.5 border-t border-border px-1 pt-1.5", children: /* @__PURE__ */ jsx(
585
- NavLink,
586
- {
587
- item: { ...item, label: seeAll(item), children: void 0 },
588
- className: "block rounded-xl px-2 py-2 text-[0.875rem]",
589
- onNavigate: () => setOpen(false)
590
- }
591
- ) })
592
- ] })
593
- ] });
566
+ },
567
+ it.href
568
+ ))
569
+ ] }, g.label ?? gi)) });
594
570
  }
595
- function SiteHeader({
596
- home = "/",
597
- brand,
598
- product,
599
- family,
600
- nav = [],
601
- search,
602
- actions,
603
- variant = "site",
604
- navOnPhone = true,
605
- menu: menuExtra,
606
- className
571
+ function SectionSwitch({
572
+ sections,
573
+ current,
574
+ onNavigate
607
575
  }) {
608
- const [open, setOpen] = useState(false);
609
- const tool = variant === "tool";
610
- const size = tool ? 24 : 28;
611
- const current = typeof family === "string" ? family : void 0;
612
- const phoneNav = navOnPhone ? nav : [];
613
- const menu = phoneNav.length > 0 || Boolean(family) || Boolean(menuExtra);
614
- const brandNode = brand ?? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center", children: [
615
- /* @__PURE__ */ jsx(Lockup, { size }),
616
- product ? /* @__PURE__ */ jsxs(Fragment, { children: [
617
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "mx-3 h-5 w-px bg-oca-hairline-strong" }),
618
- /* @__PURE__ */ jsx("span", { className: "font-medium tracking-[-0.01em]", style: { fontSize: size * 0.56 }, children: product })
619
- ] }) : null
620
- ] });
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) : (
623
- // Between md and lg the family menu and the actions share the row: tighter.
624
- /* @__PURE__ */ jsx(NavLink, { item: n, line: tool, className: tool ? void 0 : "md:max-lg:px-2.5" }, n.href)
625
- )
626
- ) }) : null;
576
+ const cols = sections.length <= 3 ? sections.length : 2;
627
577
  return /* @__PURE__ */ jsx(
628
- "header",
578
+ "nav",
629
579
  {
630
- className: cn(
631
- "sticky top-0 z-40 w-full border-b bg-background/95 backdrop-blur-md supports-[backdrop-filter]:bg-background/90",
632
- tool ? "border-border" : "border-transparent",
633
- className
634
- ),
635
- children: /* @__PURE__ */ jsxs(
580
+ "aria-label": "Sections",
581
+ className: cn("grid gap-1 bg-muted p-1", cols === sections.length ? "rounded-full" : "rounded-[1.25rem]"),
582
+ style: { gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))` },
583
+ children: sections.map((sec) => {
584
+ const on = sec.id === current.id;
585
+ return /* @__PURE__ */ jsx(
586
+ Link,
587
+ {
588
+ href: sec.href,
589
+ onClick: onNavigate,
590
+ "aria-current": on ? "true" : void 0,
591
+ className: cn(
592
+ "flex h-8 min-w-0 items-center justify-center rounded-full px-1.5 text-[0.8125rem] font-medium transition-colors",
593
+ on ? "bg-card text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
594
+ ),
595
+ children: /* @__PURE__ */ jsx("span", { className: "truncate", children: sec.label })
596
+ },
597
+ sec.id
598
+ );
599
+ })
600
+ }
601
+ );
602
+ }
603
+ function TabBar({ items }) {
604
+ return /* @__PURE__ */ jsx(
605
+ "nav",
606
+ {
607
+ "aria-label": "Pages",
608
+ "data-oca-tabbar": "",
609
+ className: "fixed inset-x-0 bottom-0 z-40 border-t border-border bg-background/90 pb-[env(safe-area-inset-bottom)] backdrop-blur-md md:hidden",
610
+ children: /* @__PURE__ */ jsx(
636
611
  "div",
637
612
  {
638
- className: cn(
639
- "flex items-center justify-between gap-4",
640
- tool ? "h-14 px-4 md:px-6" : "oca-container h-16 md:h-[4.5rem] md:max-lg:gap-2",
641
- // Three columns, the outer two each at least their content: the
642
- // navigation stays centred whatever the actions hold, so it does
643
- // not shift when they change (signed out to signed in).
644
- !tool && nav.length > 0 && "md:grid md:grid-cols-[minmax(max-content,1fr)_auto_minmax(max-content,1fr)]"
645
- ),
646
- children: [
647
- /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-center gap-1", tool ? "md:gap-1" : "justify-self-start"), children: [
648
- /* @__PURE__ */ jsxs(Link5, { href: home, className: "-ml-1 min-w-0 rounded-lg p-1", children: [
649
- brandNode,
650
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: " home" })
651
- ] }),
652
- family ? /* @__PURE__ */ jsx(FamilyMenu, { current, className: "max-md:hidden" }) : null,
653
- tool && navigation ? /* @__PURE__ */ jsx("div", { className: "ml-5", children: navigation }) : null
654
- ] }),
655
- !tool ? navigation : null,
656
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 justify-self-end", children: [
657
- search,
658
- actions,
659
- menu ? /* @__PURE__ */ jsxs(Sheet, { open, onOpenChange: setOpen, children: [
660
- /* @__PURE__ */ jsx(
661
- SheetTrigger,
613
+ className: "mx-auto grid h-14 max-w-[32rem] px-1.5",
614
+ style: { gridTemplateColumns: `repeat(${items.length}, minmax(0, 1fr))` },
615
+ children: items.map((it) => /* @__PURE__ */ jsxs(
616
+ Link,
617
+ {
618
+ href: it.href,
619
+ "aria-current": it.active ? "page" : void 0,
620
+ className: cn(
621
+ "flex min-w-0 flex-col items-center justify-center gap-1 rounded-2xl text-[0.6875rem] leading-none outline-none transition-colors [-webkit-tap-highlight-color:transparent] focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
622
+ it.active ? "text-foreground" : "text-muted-foreground hover:text-foreground"
623
+ ),
624
+ children: [
625
+ /* @__PURE__ */ jsxs(
626
+ "span",
662
627
  {
663
- className: "inline-flex size-10 items-center justify-center rounded-full text-foreground hover:bg-accent md:hidden",
664
- "aria-label": "Open menu",
665
- children: /* @__PURE__ */ jsx(Menu, { className: "size-5" })
628
+ className: cn(
629
+ "relative flex h-7 w-12 items-center justify-center rounded-full transition-[background-color,box-shadow] duration-200",
630
+ "[&_svg]:size-[1.125rem] [&_svg]:shrink-0",
631
+ it.active ? "bg-card shadow-sm ring-1 ring-border [&_svg]:stroke-2" : "[&_svg]:stroke-[1.75]"
632
+ ),
633
+ children: [
634
+ it.icon,
635
+ it.badge ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "absolute right-2.5 top-0.5 size-2 rounded-full bg-oca-orange ring-2 ring-background" }) : null
636
+ ]
666
637
  }
667
638
  ),
668
- /* @__PURE__ */ jsxs(SheetContent, { side: "right", className: "pt-16", children: [
669
- /* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Menu" }),
670
- menuExtra ? /* @__PURE__ */ jsx("div", { className: cn("flex flex-col", (phoneNav.length > 0 || family) && "border-b border-border pb-3"), children: menuExtra }) : null,
671
- phoneNav.length > 0 ? /* @__PURE__ */ jsx("nav", { "aria-label": "Main", className: "flex flex-col", children: phoneNav.map(
672
- (n) => n.children?.length ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col py-2", children: [
673
- /* @__PURE__ */ jsx("p", { className: "px-3 pb-1 text-[0.8125rem] text-muted-foreground", children: n.label }),
674
- n.children.map((c) => /* @__PURE__ */ jsx(
675
- NavLink,
676
- {
677
- item: c,
678
- className: "rounded-xl px-3 py-2.5 text-[1.0625rem]",
679
- onNavigate: () => setOpen(false)
680
- },
681
- c.href
682
- ))
683
- ] }, n.href) : /* @__PURE__ */ jsx(
684
- NavLink,
685
- {
686
- item: n,
687
- className: "rounded-xl px-3 py-3 text-[1.0625rem]",
688
- onNavigate: () => setOpen(false)
689
- },
690
- n.href
691
- )
692
- ) }) : null,
693
- family ? /* @__PURE__ */ jsxs("details", { className: cn("group", phoneNav.length > 0 && "mt-2 border-t border-border pt-4"), children: [
694
- /* @__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: [
695
- "All orangecheck sites",
696
- /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-open:rotate-180" })
697
- ] }),
698
- /* @__PURE__ */ jsx(FamilyList, { current, onNavigate: () => setOpen(false), stack: true, className: "mt-2" })
699
- ] }) : null
700
- ] })
701
- ] }) : null
702
- ] })
703
- ]
639
+ /* @__PURE__ */ jsx("span", { className: "max-w-full truncate px-0.5", children: it.label }),
640
+ it.badge ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: it.badge }) : null
641
+ ]
642
+ },
643
+ it.href
644
+ ))
704
645
  }
705
646
  )
706
647
  }
707
648
  );
708
649
  }
709
- function SkipLink({ href = "#main-content", children = "Skip to content" }) {
710
- return /* @__PURE__ */ jsx(
711
- "a",
712
- {
713
- href,
714
- className: "sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-3 focus:z-50 focus:rounded-full focus:border focus:border-border focus:bg-card focus:px-4 focus:py-2 focus:text-[0.9375rem] focus:font-medium focus:text-foreground focus:shadow-md",
715
- children
716
- }
717
- );
718
- }
719
- var BANNER_TONE = {
650
+ function tabsFor(groups) {
651
+ const items = groups.flatMap((g) => g.items);
652
+ return items.length >= 2 && items.length <= 5 && items.every((it) => it.icon) ? items : null;
653
+ }
654
+ var activeItem = (groups) => groups.flatMap((g) => g.items).find((it) => it.active);
655
+ var warned = /* @__PURE__ */ new Set();
656
+ function warnDuplicateLabels(groups) {
657
+ if (typeof process === "undefined" || process.env.NODE_ENV === "production") return;
658
+ const seen = /* @__PURE__ */ new Set();
659
+ for (const it of groups.flatMap((g) => g.items)) {
660
+ if (seen.has(it.label) && !warned.has(it.label)) {
661
+ warned.add(it.label);
662
+ console.warn(`AppShell: two pages are labelled "${it.label}"; give each its own name.`);
663
+ }
664
+ seen.add(it.label);
665
+ }
666
+ }
667
+ function AppShell({
668
+ nav,
669
+ sections,
670
+ activeSection,
671
+ page: pageOverride,
672
+ persistent = [],
673
+ home = "/",
674
+ family,
675
+ account,
676
+ banner,
677
+ footer,
678
+ children,
679
+ className
680
+ }) {
681
+ const [open, setOpen] = useState(false);
682
+ const current = sections && sections.length > 0 ? sections.find((sec) => sec.id === activeSection) ?? sections.find((sec) => activeItem(sec.groups)) ?? sections[0] : void 0;
683
+ const groups = current ? [...current.groups, ...persistent] : [...nav ?? [], ...persistent];
684
+ warnDuplicateLabels(groups);
685
+ const tabs = current ? null : tabsFor(groups);
686
+ const page = activeItem(groups);
687
+ const place = useMemo(
688
+ () => ({
689
+ section: current ? current.title ?? current.label : void 0,
690
+ page: pageOverride ?? page?.label
691
+ }),
692
+ [current, page?.label, pageOverride]
693
+ );
694
+ const familyMenu = family ? /* @__PURE__ */ jsx(FamilyMenu, { current: typeof family === "string" ? family : void 0 }) : null;
695
+ const switcher = sections && current && sections.length > 1 ? /* @__PURE__ */ jsx(SectionSwitch, { sections, current, onNavigate: () => setOpen(false) }) : null;
696
+ return /* @__PURE__ */ jsx(ShellContext.Provider, { value: place, children: /* @__PURE__ */ jsxs(
697
+ "div",
698
+ {
699
+ className: cn(
700
+ "min-h-dvh bg-background",
701
+ tabs && "max-md:pb-[calc(3.5rem_+_env(safe-area-inset-bottom))]",
702
+ className
703
+ ),
704
+ children: [
705
+ /* @__PURE__ */ jsxs("div", { className: "sticky top-0 z-40 border-b border-border bg-background/90 backdrop-blur-md lg:hidden", children: [
706
+ /* @__PURE__ */ jsxs("div", { className: "flex h-14 items-center gap-2 px-3", children: [
707
+ /* @__PURE__ */ jsxs(Sheet, { open, onOpenChange: setOpen, children: [
708
+ /* @__PURE__ */ jsx(
709
+ SheetTrigger,
710
+ {
711
+ className: cn(
712
+ "inline-flex size-10 items-center justify-center rounded-full hover:bg-accent",
713
+ // The tab bar holds every page; the sheet is left for a footer.
714
+ tabs && !footer && "max-md:hidden"
715
+ ),
716
+ "aria-label": "Open navigation",
717
+ children: /* @__PURE__ */ jsx(Menu, { className: "size-5" })
718
+ }
719
+ ),
720
+ /* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "flex flex-col gap-6 overflow-y-auto p-4 pt-16", children: [
721
+ /* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Navigation" }),
722
+ switcher,
723
+ /* @__PURE__ */ jsx("div", { className: tabs ? "max-md:hidden" : void 0, children: /* @__PURE__ */ jsx(SideNav, { groups, onNavigate: () => setOpen(false) }) }),
724
+ footer ? /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer }) : null
725
+ ] })
726
+ ] }),
727
+ /* @__PURE__ */ jsx(Link, { href: home, "aria-label": "Home", className: "rounded-lg p-1", children: /* @__PURE__ */ jsx(Lockup, { size: 22 }) }),
728
+ familyMenu,
729
+ /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center", children: account })
730
+ ] }),
731
+ place.page ? /* @__PURE__ */ jsxs(
732
+ "div",
733
+ {
734
+ className: cn(
735
+ "flex h-9 items-center gap-1.5 border-t border-border px-4 text-[0.875rem]",
736
+ // The active tab already names the page.
737
+ tabs && !pageOverride && "max-md:hidden"
738
+ ),
739
+ children: [
740
+ place.section ? /* @__PURE__ */ jsxs(Fragment, { children: [
741
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: place.section }),
742
+ /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-muted-foreground" })
743
+ ] }) : null,
744
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: place.page })
745
+ ]
746
+ }
747
+ ) : null
748
+ ] }),
749
+ /* @__PURE__ */ jsxs("div", { className: "mx-auto flex w-full max-w-[90rem]", children: [
750
+ /* @__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: [
751
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
752
+ /* @__PURE__ */ jsx(Link, { href: home, className: "px-2", "aria-label": "Home", children: /* @__PURE__ */ jsx(Lockup, { size: 26 }) }),
753
+ familyMenu
754
+ ] }),
755
+ switcher,
756
+ /* @__PURE__ */ jsx(SideNav, { groups }),
757
+ /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer })
758
+ ] }),
759
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
760
+ /* @__PURE__ */ jsx("div", { className: "hidden h-[4.5rem] items-center justify-end gap-3 px-8 lg:flex", children: account }),
761
+ banner ? /* @__PURE__ */ jsx("div", { className: "px-4 pb-2 pt-4 md:px-8 lg:pt-0", children: banner }) : null,
762
+ /* @__PURE__ */ jsx("main", { id: "main-content", className: "flex-1 px-4 pb-16 pt-6 md:px-8 lg:pt-2", children: /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-[72rem]", children }) })
763
+ ] })
764
+ ] }),
765
+ tabs ? /* @__PURE__ */ jsx(TabBar, { items: tabs }) : null
766
+ ]
767
+ }
768
+ ) });
769
+ }
770
+ function AccountMenu({
771
+ name,
772
+ detail,
773
+ items,
774
+ nameFrom = "sm"
775
+ }) {
776
+ const initial = name.trim().charAt(0).toUpperCase() || "\xB7";
777
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
778
+ /* @__PURE__ */ jsxs(
779
+ DropdownMenuTrigger,
780
+ {
781
+ className: cn(
782
+ "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",
783
+ nameFrom === "lg" ? "lg:pr-3.5" : "sm:pr-3.5"
784
+ ),
785
+ "aria-label": `${name}, account menu`,
786
+ children: [
787
+ /* @__PURE__ */ jsx(
788
+ "span",
789
+ {
790
+ "aria-hidden": true,
791
+ "data-initial": initial,
792
+ className: "flex size-8 items-center justify-center rounded-full bg-foreground text-[0.8125rem] font-medium text-background before:content-[attr(data-initial)]"
793
+ }
794
+ ),
795
+ /* @__PURE__ */ jsx("span", { className: cn("max-w-[10rem] truncate", nameFrom === "lg" ? "max-lg:hidden" : "max-sm:hidden"), children: name })
796
+ ]
797
+ }
798
+ ),
799
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-64", children: [
800
+ /* @__PURE__ */ jsxs(DropdownMenuLabel, { className: "flex flex-col gap-0.5", children: [
801
+ /* @__PURE__ */ jsx("span", { className: "truncate text-[0.9375rem] font-medium text-foreground", children: name }),
802
+ detail ? /* @__PURE__ */ jsx("span", { className: "truncate font-mono text-[0.75rem]", children: detail }) : null
803
+ ] }),
804
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
805
+ items.map(
806
+ (it, i) => it === "separator" ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}, `sep-${i}`) : it.href ? /* @__PURE__ */ jsx(DropdownMenuItem, { asChild: true, destructive: it.destructive, children: /* @__PURE__ */ jsxs(Link, { href: it.href, children: [
807
+ it.icon,
808
+ it.label
809
+ ] }) }, it.label) : /* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: it.onSelect, destructive: it.destructive, children: [
810
+ it.icon,
811
+ it.label
812
+ ] }, it.label)
813
+ )
814
+ ] })
815
+ ] });
816
+ }
817
+ function ThemeToggle({ className }) {
818
+ const { theme, setTheme } = useTheme();
819
+ const [mounted, setMounted] = useState(false);
820
+ useEffect(() => setMounted(true), []);
821
+ const current = mounted ? theme ?? "system" : "system";
822
+ const next = current === "light" ? "dark" : current === "dark" ? "system" : "light";
823
+ const Icon = current === "light" ? Sun : current === "dark" ? Moon : SunMoon;
824
+ return /* @__PURE__ */ jsx(
825
+ "button",
826
+ {
827
+ type: "button",
828
+ onClick: () => setTheme(next),
829
+ "aria-label": `Theme: ${current}. Switch to ${next}`,
830
+ title: `Theme: ${current}`,
831
+ className: cn(
832
+ "inline-flex size-10 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
833
+ className
834
+ ),
835
+ children: /* @__PURE__ */ jsx(Icon, { className: "size-[1.125rem]" })
836
+ }
837
+ );
838
+ }
839
+ function NavLink({
840
+ item,
841
+ className,
842
+ onNavigate,
843
+ line = false
844
+ }) {
845
+ const cls = cn(
846
+ "rounded-full px-3 py-2 text-[0.9375rem] transition-colors",
847
+ item.active ? "text-foreground" : "text-muted-foreground hover:text-foreground",
848
+ line && "relative after:absolute after:inset-x-3 after:-bottom-[0.625rem] after:h-0.5 after:rounded-full",
849
+ line && item.active && "after:bg-foreground",
850
+ className
851
+ );
852
+ if (item.external) {
853
+ return /* @__PURE__ */ jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: item.label });
854
+ }
855
+ return /* @__PURE__ */ jsx(Link, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: item.label });
856
+ }
857
+ function NavRow({ item, onNavigate }) {
858
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
859
+ /* @__PURE__ */ jsx("span", { className: "text-[0.9375rem] font-medium leading-6 text-foreground", children: item.label }),
860
+ item.description ? /* @__PURE__ */ jsx("span", { className: "text-[0.8125rem] leading-snug text-muted-foreground", children: item.description }) : null
861
+ ] });
862
+ const cls = cn(
863
+ "flex flex-col gap-0.5 rounded-xl px-3 py-2 transition-colors hover:bg-accent",
864
+ item.active && "bg-muted hover:bg-muted dark:bg-white/[0.06]"
865
+ );
866
+ return item.external ? /* @__PURE__ */ jsx("a", { href: item.href, className: cls, rel: "noreferrer", onClick: onNavigate, children: body }) : /* @__PURE__ */ jsx(Link, { href: item.href, className: cls, "aria-current": item.active ? "page" : void 0, onClick: onNavigate, children: body });
867
+ }
868
+ var seeAll = (item) => typeof item.label === "string" ? `All ${item.label.toLowerCase()}` : "See all";
869
+ function NavDropdown({ item }) {
870
+ const [open, setOpen] = useState(false);
871
+ const active = item.active || item.children?.some((c) => c.active);
872
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
873
+ /* @__PURE__ */ jsxs(
874
+ PopoverTrigger,
875
+ {
876
+ className: cn(
877
+ "group inline-flex items-center gap-1 rounded-full py-2 pl-3 pr-2.5 text-[0.9375rem] transition-colors md:max-lg:pl-2.5 md:max-lg:pr-2",
878
+ active ? "text-foreground" : "text-muted-foreground hover:text-foreground data-[state=open]:text-foreground"
879
+ ),
880
+ children: [
881
+ item.label,
882
+ /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-3.5 transition-transform duration-200 group-data-[state=open]:rotate-180" })
883
+ ]
884
+ }
885
+ ),
886
+ /* @__PURE__ */ jsxs(PopoverContent, { align: "center", sideOffset: 10, className: "w-[min(calc(100vw-2rem),26rem)] p-2", children: [
887
+ /* @__PURE__ */ jsx("ul", { className: "flex flex-col", children: item.children?.map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(NavRow, { item: c, onNavigate: () => setOpen(false) }) }, c.href)) }),
888
+ /* @__PURE__ */ jsx("div", { className: "mt-1.5 border-t border-border px-1 pt-1.5", children: /* @__PURE__ */ jsx(
889
+ NavLink,
890
+ {
891
+ item: { ...item, label: seeAll(item), children: void 0 },
892
+ className: "block rounded-xl px-2 py-2 text-[0.875rem]",
893
+ onNavigate: () => setOpen(false)
894
+ }
895
+ ) })
896
+ ] })
897
+ ] });
898
+ }
899
+ function SiteHeader({
900
+ home = "/",
901
+ brand,
902
+ product,
903
+ family,
904
+ nav = [],
905
+ search,
906
+ actions,
907
+ variant = "site",
908
+ navOnPhone = true,
909
+ menu: menuExtra,
910
+ className
911
+ }) {
912
+ const [open, setOpen] = useState(false);
913
+ const tool = variant === "tool";
914
+ const size = tool ? 24 : 28;
915
+ const current = typeof family === "string" ? family : void 0;
916
+ const phoneNav = navOnPhone ? nav : [];
917
+ const menu = phoneNav.length > 0 || Boolean(family) || Boolean(menuExtra);
918
+ const brandNode = brand ?? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center", children: [
919
+ /* @__PURE__ */ jsx(Lockup, { size }),
920
+ product ? /* @__PURE__ */ jsxs(Fragment, { children: [
921
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "mx-3 h-5 w-px bg-oca-hairline-strong" }),
922
+ /* @__PURE__ */ jsx("span", { className: "font-medium tracking-[-0.01em]", style: { fontSize: size * 0.56 }, children: product })
923
+ ] }) : null
924
+ ] });
925
+ const navigation = nav.length > 0 ? /* @__PURE__ */ jsx("nav", { "aria-label": "Main", className: "hidden items-center gap-1 md:flex", children: nav.map(
926
+ (n) => n.children?.length ? /* @__PURE__ */ jsx(NavDropdown, { item: n }, n.href) : (
927
+ // Between md and lg the family menu and the actions share the row: tighter.
928
+ /* @__PURE__ */ jsx(NavLink, { item: n, line: tool, className: tool ? void 0 : "md:max-lg:px-2.5" }, n.href)
929
+ )
930
+ ) }) : null;
931
+ return /* @__PURE__ */ jsx(
932
+ "header",
933
+ {
934
+ className: cn(
935
+ "sticky top-0 z-40 w-full border-b bg-background/95 backdrop-blur-md supports-[backdrop-filter]:bg-background/90",
936
+ tool ? "border-border" : "border-transparent",
937
+ className
938
+ ),
939
+ children: /* @__PURE__ */ jsxs(
940
+ "div",
941
+ {
942
+ className: cn(
943
+ "flex items-center justify-between gap-4",
944
+ tool ? "h-14 px-4 md:px-6" : "oca-container h-16 md:h-[4.5rem] md:max-lg:gap-2",
945
+ // Three columns, the outer two each at least their content: the
946
+ // navigation stays centred whatever the actions hold, so it does
947
+ // not shift when they change (signed out to signed in).
948
+ !tool && nav.length > 0 && "md:grid md:grid-cols-[minmax(max-content,1fr)_auto_minmax(max-content,1fr)]"
949
+ ),
950
+ children: [
951
+ /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-center gap-1", tool ? "md:gap-1" : "justify-self-start"), children: [
952
+ /* @__PURE__ */ jsxs(Link, { href: home, className: "-ml-1 min-w-0 rounded-lg p-1", children: [
953
+ brandNode,
954
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: " home" })
955
+ ] }),
956
+ family ? /* @__PURE__ */ jsx(FamilyMenu, { current, className: "max-md:hidden" }) : null,
957
+ tool && navigation ? /* @__PURE__ */ jsx("div", { className: "ml-5", children: navigation }) : null
958
+ ] }),
959
+ !tool ? navigation : null,
960
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 justify-self-end", children: [
961
+ search,
962
+ actions,
963
+ menu ? /* @__PURE__ */ jsxs(Sheet, { open, onOpenChange: setOpen, children: [
964
+ /* @__PURE__ */ jsx(
965
+ SheetTrigger,
966
+ {
967
+ className: "inline-flex size-10 items-center justify-center rounded-full text-foreground hover:bg-accent md:hidden",
968
+ "aria-label": "Open menu",
969
+ children: /* @__PURE__ */ jsx(Menu, { className: "size-5" })
970
+ }
971
+ ),
972
+ /* @__PURE__ */ jsxs(SheetContent, { side: "right", className: "pt-16", children: [
973
+ /* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Menu" }),
974
+ menuExtra ? /* @__PURE__ */ jsx("div", { className: cn("flex flex-col", (phoneNav.length > 0 || family) && "border-b border-border pb-3"), children: menuExtra }) : null,
975
+ phoneNav.length > 0 ? /* @__PURE__ */ jsx("nav", { "aria-label": "Main", className: "flex flex-col", children: phoneNav.map(
976
+ (n) => n.children?.length ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col py-2", children: [
977
+ /* @__PURE__ */ jsx("p", { className: "px-3 pb-1 text-[0.8125rem] text-muted-foreground", children: n.label }),
978
+ n.children.map((c) => /* @__PURE__ */ jsx(
979
+ NavLink,
980
+ {
981
+ item: c,
982
+ className: "rounded-xl px-3 py-2.5 text-[1.0625rem]",
983
+ onNavigate: () => setOpen(false)
984
+ },
985
+ c.href
986
+ ))
987
+ ] }, n.href) : /* @__PURE__ */ jsx(
988
+ NavLink,
989
+ {
990
+ item: n,
991
+ className: "rounded-xl px-3 py-3 text-[1.0625rem]",
992
+ onNavigate: () => setOpen(false)
993
+ },
994
+ n.href
995
+ )
996
+ ) }) : null,
997
+ family ? /* @__PURE__ */ jsxs("details", { className: cn("group", phoneNav.length > 0 && "mt-2 border-t border-border pt-4"), children: [
998
+ /* @__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: [
999
+ "All orangecheck sites",
1000
+ /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-open:rotate-180" })
1001
+ ] }),
1002
+ /* @__PURE__ */ jsx(FamilyList, { current, onNavigate: () => setOpen(false), stack: true, className: "mt-2" })
1003
+ ] }) : null
1004
+ ] })
1005
+ ] }) : null
1006
+ ] })
1007
+ ]
1008
+ }
1009
+ )
1010
+ }
1011
+ );
1012
+ }
1013
+ function SkipLink({ href = "#main-content", children = "Skip to content" }) {
1014
+ return /* @__PURE__ */ jsx(
1015
+ "a",
1016
+ {
1017
+ href,
1018
+ className: "sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-3 focus:z-50 focus:rounded-full focus:border focus:border-border focus:bg-card focus:px-4 focus:py-2 focus:text-[0.9375rem] focus:font-medium focus:text-foreground focus:shadow-md",
1019
+ children
1020
+ }
1021
+ );
1022
+ }
1023
+ var BANNER_TONE = {
720
1024
  neutral: "border-border bg-muted",
721
1025
  brand: "border-[color-mix(in_oklab,var(--oca-orange)_30%,var(--border))] bg-[color-mix(in_oklab,var(--oca-orange)_9%,var(--background))]",
722
1026
  danger: "border-[color-mix(in_oklab,var(--destructive)_35%,var(--border))] bg-[color-mix(in_oklab,var(--destructive)_8%,var(--background))]"
@@ -747,7 +1051,7 @@ function SiteBanner({
747
1051
  var FOOT_LINK = "inline-flex min-h-11 items-center transition-colors hover:text-foreground md:min-h-0";
748
1052
  function LegalRow({ links }) {
749
1053
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-x-6 gap-y-2 sm:flex-row sm:items-center sm:justify-between", children: [
750
- /* @__PURE__ */ jsx("nav", { "aria-label": "Legal", children: /* @__PURE__ */ jsx("ul", { className: "flex flex-wrap gap-x-5", children: links.map((l) => /* @__PURE__ */ jsx("li", { children: l.href.startsWith("/") ? /* @__PURE__ */ jsx(Link5, { href: l.href, className: FOOT_LINK, children: l.label }) : /* @__PURE__ */ jsx("a", { href: l.href, className: FOOT_LINK, children: l.label }) }, l.href)) }) }),
1054
+ /* @__PURE__ */ jsx("nav", { "aria-label": "Legal", children: /* @__PURE__ */ jsx("ul", { className: "flex flex-wrap gap-x-5", children: links.map((l) => /* @__PURE__ */ jsx("li", { children: l.href.startsWith("/") ? /* @__PURE__ */ jsx(Link, { href: l.href, className: FOOT_LINK, children: l.label }) : /* @__PURE__ */ jsx("a", { href: l.href, className: FOOT_LINK, children: l.label }) }, l.href)) }) }),
751
1055
  /* @__PURE__ */ jsxs("p", { children: [
752
1056
  "\xA9 ",
753
1057
  (/* @__PURE__ */ new Date()).getFullYear(),
@@ -837,6 +1141,25 @@ function SiteFooter({
837
1141
  ] }) }) : null
838
1142
  ] });
839
1143
  }
1144
+ function OchkIoFooter({ columns = OCHK_IO_FOOTER, className }) {
1145
+ return /* @__PURE__ */ jsx(
1146
+ SiteFooter,
1147
+ {
1148
+ columns,
1149
+ family: true,
1150
+ legal: true,
1151
+ fineprint: "Open protocols on Bitcoin. Anyone can check the result.",
1152
+ meta: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
1153
+ /* @__PURE__ */ jsxs("p", { children: [
1154
+ "Open-source work on orangecheck is ",
1155
+ /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: "supported by OpenSats." })
1156
+ ] }),
1157
+ /* @__PURE__ */ jsx(ThemeToggle, { className: "-mx-3" })
1158
+ ] }),
1159
+ className
1160
+ }
1161
+ );
1162
+ }
840
1163
  function IsoCheck({ size = 360, settle = false, shadow = true, tilt = false, title, className }) {
841
1164
  const ref = useRef(null);
842
1165
  useEffect(() => {
@@ -922,12 +1245,12 @@ function SignInFrame({
922
1245
  children: [
923
1246
  /* @__PURE__ */ jsxs("section", { className: "flex flex-col px-4 pb-8 pt-5 sm:px-8 lg:px-14 lg:pt-8", children: [
924
1247
  /* @__PURE__ */ jsxs("header", { className: "flex items-center justify-between gap-4", children: [
925
- /* @__PURE__ */ jsxs(Link5, { href: home, className: "w-fit rounded-lg", children: [
1248
+ /* @__PURE__ */ jsxs(Link, { href: home, className: "w-fit rounded-lg", children: [
926
1249
  brand ?? /* @__PURE__ */ jsx(Lockup, { size: 28 }),
927
1250
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: " home" })
928
1251
  ] }),
929
1252
  back === void 0 ? /* @__PURE__ */ jsx(
930
- Link5,
1253
+ Link,
931
1254
  {
932
1255
  href: home,
933
1256
  className: "text-[0.9375rem] text-muted-foreground underline-offset-4 hover:text-foreground hover:underline",
@@ -993,21 +1316,10 @@ forwardRef(function Separator3({ className, orientation = "horizontal", decorati
993
1316
  }
994
1317
  );
995
1318
  });
996
- function sharedContext(name, initial) {
997
- const key = /* @__PURE__ */ Symbol.for(`@orangecheck/app-design/${name}`);
998
- const store = globalThis;
999
- return store[key] ?? (store[key] = createContext(initial));
1000
- }
1001
-
1002
- // src/lib/density.ts
1003
1319
  var DensityContext = sharedContext("density", "comfortable");
1004
1320
  function DensityProvider({ density, children }) {
1005
1321
  return createElement(DensityContext.Provider, { value: density }, children);
1006
1322
  }
1007
- var ShellContext = sharedContext("shell-place", {});
1008
- function useShellPlace() {
1009
- return useContext(ShellContext);
1010
- }
1011
1323
  var buttonVariants = cva(
1012
1324
  [
1013
1325
  "inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap rounded-full font-medium",
@@ -1139,6 +1451,7 @@ function OnThisPage({
1139
1451
  ] })
1140
1452
  );
1141
1453
  }
1454
+ var InDocsContext = sharedContext("in-docs", false);
1142
1455
  var STATUS_WORDS = /* @__PURE__ */ new Set(["live", "testing", "not-yet", "paused", "good", "caution", "refused"]);
1143
1456
  var pathOf = (href) => href.split(/[?#]/)[0].replace(/(.)\/$/, "$1");
1144
1457
  function DocsNav({
@@ -1194,394 +1507,131 @@ function DocsNav({
1194
1507
  className: cn("size-3.5 shrink-0 text-oca-subtle transition-transform duration-200", open && "rotate-90")
1195
1508
  }
1196
1509
  )
1197
- ]
1198
- }
1199
- ),
1200
- /* @__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) => {
1201
- const on = pathOf(item.href) === here;
1202
- 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;
1203
- return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
1204
- Link5,
1205
- {
1206
- href: item.href,
1207
- ref: on ? activeRef : void 0,
1208
- onClick: onNavigate,
1209
- "aria-current": on ? "page" : void 0,
1210
- className: cn(
1211
- "-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",
1212
- on ? "border-foreground font-medium text-foreground" : "border-transparent text-muted-foreground hover:border-oca-hairline-strong hover:text-foreground"
1213
- ),
1214
- children: [
1215
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children: item.label }),
1216
- badge
1217
- ]
1218
- }
1219
- ) }, item.href);
1220
- }) })
1221
- ] }, section.label);
1222
- }) });
1223
- }
1224
- var DOCS_HEADER_NAV = OCHK_IO_NAV.map((n) => n.href === DOCS_HREF ? { ...n, active: true } : n);
1225
- function DocsShell({
1226
- nav,
1227
- current,
1228
- header,
1229
- search,
1230
- actions,
1231
- breadcrumbs,
1232
- toc,
1233
- pager,
1234
- footer,
1235
- children
1236
- }) {
1237
- const [menu, setMenu] = useState(false);
1238
- useEffect(() => setMenu(false), [current]);
1239
- const read = useHeadings("#docs-content", current);
1240
- const items = toc ?? read.items;
1241
- const activeId = toc ? void 0 : read.activeId;
1242
- const here = pathOf(current);
1243
- const place = useMemo(() => {
1244
- for (const s of nav) {
1245
- const it = s.items.find((i) => pathOf(i.href) === here);
1246
- if (it) return { section: s.label, page: it.label };
1247
- }
1248
- return null;
1249
- }, [nav, here]);
1250
- return /* @__PURE__ */ jsxs("div", { className: "flex min-h-dvh flex-col bg-background", children: [
1251
- /* @__PURE__ */ jsx(SkipLink, {}),
1252
- header ?? /* @__PURE__ */ jsx(SiteHeader, { home: OCHK_IO, family: "docs", nav: DOCS_HEADER_NAV, search, actions }),
1253
- /* @__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: [
1254
- /* @__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: [
1255
- /* @__PURE__ */ jsx(PanelLeft, { "aria-hidden": true, className: "size-[1.125rem] shrink-0" }),
1256
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Docs menu. " }),
1257
- place ? /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1258
- /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: place.section }),
1259
- /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-oca-subtle" }),
1260
- /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: place.page })
1261
- ] }) : /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Docs" })
1262
- ] }),
1263
- /* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "w-[min(88vw,22rem)] gap-0 p-0", children: [
1264
- /* @__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" }) }),
1265
- /* @__PURE__ */ jsx("div", { className: "overflow-y-auto p-3", children: /* @__PURE__ */ jsx(DocsNav, { sections: nav, current, onNavigate: () => setMenu(false) }) })
1266
- ] })
1267
- ] }) }) }),
1268
- /* @__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: [
1269
- /* @__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 }) }),
1270
- /* @__PURE__ */ jsxs("main", { id: "main-content", className: "min-w-0 pb-16 pt-6 md:pt-8", children: [
1271
- breadcrumbs ? /* @__PURE__ */ jsx("div", { className: "mb-6 max-lg:hidden", children: breadcrumbs }) : null,
1272
- items.length > 1 ? /* @__PURE__ */ jsxs("details", { className: "group mb-8 rounded-2xl border border-border bg-card xl:hidden", children: [
1273
- /* @__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: [
1274
- "On this page",
1275
- /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-open:rotate-180" })
1276
- ] }),
1277
- /* @__PURE__ */ jsx(OnThisPage, { items, activeId, title: null, className: "px-4 pb-4" })
1278
- ] }) : null,
1279
- /* @__PURE__ */ jsx("article", { id: "docs-content", className: "max-w-[46rem]", children }),
1280
- pager ? /* @__PURE__ */ jsx("div", { className: "mt-16 max-w-[46rem]", children: pager }) : null
1281
- ] }),
1282
- /* @__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 })
1283
- ] }) }),
1284
- footer ?? /* @__PURE__ */ jsx(SiteFooter, { columns: OCHK_IO_FOOTER, family: true, legal: true, signature: false })
1285
- ] });
1286
- }
1287
- function SideNav({ groups, onNavigate }) {
1288
- 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: [
1289
- g.label ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-1 text-[0.8125rem] text-muted-foreground", children: g.label }) : null,
1290
- g.items.map((it) => /* @__PURE__ */ jsxs(
1291
- Link5,
1292
- {
1293
- href: it.href,
1294
- onClick: onNavigate,
1295
- "aria-current": it.active ? "page" : void 0,
1296
- className: cn(
1297
- "flex h-9 items-center gap-3 rounded-xl px-3 text-[0.9375rem] transition-colors",
1298
- "[&_svg]:size-[1.0625rem] [&_svg]:shrink-0",
1299
- it.active ? "bg-card text-foreground shadow-sm ring-1 ring-border [&_svg]:text-foreground" : "text-muted-foreground hover:bg-accent hover:text-foreground"
1300
- ),
1301
- children: [
1302
- it.icon,
1303
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: it.label }),
1304
- it.badge ? /* @__PURE__ */ jsx("span", { className: "shrink-0", children: it.badge }) : null
1305
- ]
1306
- },
1307
- it.href
1308
- ))
1309
- ] }, g.label ?? gi)) });
1310
- }
1311
- function SectionSwitch({
1312
- sections,
1313
- current,
1314
- onNavigate
1315
- }) {
1316
- const cols = sections.length <= 3 ? sections.length : 2;
1317
- return /* @__PURE__ */ jsx(
1318
- "nav",
1319
- {
1320
- "aria-label": "Sections",
1321
- className: cn("grid gap-1 bg-muted p-1", cols === sections.length ? "rounded-full" : "rounded-[1.25rem]"),
1322
- style: { gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))` },
1323
- children: sections.map((sec) => {
1324
- const on = sec.id === current.id;
1325
- return /* @__PURE__ */ jsx(
1326
- Link5,
1327
- {
1328
- href: sec.href,
1329
- onClick: onNavigate,
1330
- "aria-current": on ? "true" : void 0,
1331
- className: cn(
1332
- "flex h-8 min-w-0 items-center justify-center rounded-full px-1.5 text-[0.8125rem] font-medium transition-colors",
1333
- on ? "bg-card text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
1334
- ),
1335
- children: /* @__PURE__ */ jsx("span", { className: "truncate", children: sec.label })
1336
- },
1337
- sec.id
1338
- );
1339
- })
1340
- }
1341
- );
1342
- }
1343
- function TabBar({ items }) {
1344
- return /* @__PURE__ */ jsx(
1345
- "nav",
1346
- {
1347
- "aria-label": "Pages",
1348
- "data-oca-tabbar": "",
1349
- className: "fixed inset-x-0 bottom-0 z-40 border-t border-border bg-background/90 pb-[env(safe-area-inset-bottom)] backdrop-blur-md md:hidden",
1350
- children: /* @__PURE__ */ jsx(
1351
- "div",
1352
- {
1353
- className: "mx-auto grid h-14 max-w-[32rem] px-1.5",
1354
- style: { gridTemplateColumns: `repeat(${items.length}, minmax(0, 1fr))` },
1355
- children: items.map((it) => /* @__PURE__ */ jsxs(
1356
- Link5,
1357
- {
1358
- href: it.href,
1359
- "aria-current": it.active ? "page" : void 0,
1360
- className: cn(
1361
- "flex min-w-0 flex-col items-center justify-center gap-1 rounded-2xl text-[0.6875rem] leading-none outline-none transition-colors [-webkit-tap-highlight-color:transparent] focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
1362
- it.active ? "text-foreground" : "text-muted-foreground hover:text-foreground"
1363
- ),
1364
- children: [
1365
- /* @__PURE__ */ jsxs(
1366
- "span",
1367
- {
1368
- className: cn(
1369
- "relative flex h-7 w-12 items-center justify-center rounded-full transition-[background-color,box-shadow] duration-200",
1370
- "[&_svg]:size-[1.125rem] [&_svg]:shrink-0",
1371
- it.active ? "bg-card shadow-sm ring-1 ring-border [&_svg]:stroke-2" : "[&_svg]:stroke-[1.75]"
1372
- ),
1373
- children: [
1374
- it.icon,
1375
- it.badge ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "absolute right-2.5 top-0.5 size-2 rounded-full bg-oca-orange ring-2 ring-background" }) : null
1376
- ]
1377
- }
1378
- ),
1379
- /* @__PURE__ */ jsx("span", { className: "max-w-full truncate px-0.5", children: it.label }),
1380
- it.badge ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: it.badge }) : null
1381
- ]
1382
- },
1383
- it.href
1384
- ))
1510
+ ]
1385
1511
  }
1386
- )
1387
- }
1388
- );
1389
- }
1390
- function tabsFor(groups) {
1391
- const items = groups.flatMap((g) => g.items);
1392
- return items.length >= 2 && items.length <= 5 && items.every((it) => it.icon) ? items : null;
1393
- }
1394
- var activeItem = (groups) => groups.flatMap((g) => g.items).find((it) => it.active);
1395
- var warned = /* @__PURE__ */ new Set();
1396
- function warnDuplicateLabels(groups) {
1397
- if (typeof process === "undefined" || process.env.NODE_ENV === "production") return;
1398
- const seen = /* @__PURE__ */ new Set();
1399
- for (const it of groups.flatMap((g) => g.items)) {
1400
- if (seen.has(it.label) && !warned.has(it.label)) {
1401
- warned.add(it.label);
1402
- console.warn(`AppShell: two pages are labelled "${it.label}"; give each its own name.`);
1403
- }
1404
- seen.add(it.label);
1405
- }
1512
+ ),
1513
+ /* @__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) => {
1514
+ const on = pathOf(item.href) === here;
1515
+ 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;
1516
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
1517
+ Link,
1518
+ {
1519
+ href: item.href,
1520
+ ref: on ? activeRef : void 0,
1521
+ onClick: onNavigate,
1522
+ "aria-current": on ? "page" : void 0,
1523
+ className: cn(
1524
+ "-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",
1525
+ on ? "border-foreground font-medium text-foreground" : "border-transparent text-muted-foreground hover:border-oca-hairline-strong hover:text-foreground"
1526
+ ),
1527
+ children: [
1528
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children: item.label }),
1529
+ badge
1530
+ ]
1531
+ }
1532
+ ) }, item.href);
1533
+ }) })
1534
+ ] }, section.label);
1535
+ }) });
1406
1536
  }
1407
- function AppShell({
1537
+ var DOCS_HEADER_NAV = OCHK_IO_NAV.map((n) => n.href === DOCS_HREF ? { ...n, active: true } : n);
1538
+ function DocsShell({
1408
1539
  nav,
1409
- sections,
1410
- activeSection,
1411
- page: pageOverride,
1412
- persistent = [],
1413
- home = "/",
1414
- account,
1415
- banner,
1540
+ current,
1541
+ navCurrent,
1542
+ header,
1543
+ search,
1544
+ actions,
1545
+ breadcrumbs,
1546
+ toc,
1547
+ pager,
1416
1548
  footer,
1417
- children,
1418
- className
1549
+ children
1419
1550
  }) {
1420
- const [open, setOpen] = useState(false);
1421
- const current = sections && sections.length > 0 ? sections.find((sec) => sec.id === activeSection) ?? sections.find((sec) => activeItem(sec.groups)) ?? sections[0] : void 0;
1422
- const groups = current ? [...current.groups, ...persistent] : [...nav ?? [], ...persistent];
1423
- warnDuplicateLabels(groups);
1424
- const tabs = current ? null : tabsFor(groups);
1425
- const page = activeItem(groups);
1426
- const place = useMemo(
1427
- () => ({
1428
- section: current ? current.title ?? current.label : void 0,
1429
- page: pageOverride ?? page?.label
1430
- }),
1431
- [current, page?.label, pageOverride]
1432
- );
1433
- const switcher = sections && current && sections.length > 1 ? /* @__PURE__ */ jsx(SectionSwitch, { sections, current, onNavigate: () => setOpen(false) }) : null;
1434
- return /* @__PURE__ */ jsx(ShellContext.Provider, { value: place, children: /* @__PURE__ */ jsxs(
1435
- "div",
1436
- {
1437
- className: cn(
1438
- "min-h-dvh bg-background",
1439
- tabs && "max-md:pb-[calc(3.5rem_+_env(safe-area-inset-bottom))]",
1440
- className
1441
- ),
1442
- children: [
1443
- /* @__PURE__ */ jsxs("div", { className: "sticky top-0 z-40 border-b border-border bg-background/90 backdrop-blur-md lg:hidden", children: [
1444
- /* @__PURE__ */ jsxs("div", { className: "flex h-14 items-center gap-2 px-3", children: [
1445
- /* @__PURE__ */ jsxs(Sheet, { open, onOpenChange: setOpen, children: [
1446
- /* @__PURE__ */ jsx(
1447
- SheetTrigger,
1448
- {
1449
- className: cn(
1450
- "inline-flex size-10 items-center justify-center rounded-full hover:bg-accent",
1451
- // The tab bar holds every page; the sheet is left for a footer.
1452
- tabs && !footer && "max-md:hidden"
1453
- ),
1454
- "aria-label": "Open navigation",
1455
- children: /* @__PURE__ */ jsx(Menu, { className: "size-5" })
1456
- }
1457
- ),
1458
- /* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "flex flex-col gap-6 overflow-y-auto p-4 pt-16", children: [
1459
- /* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Navigation" }),
1460
- switcher,
1461
- /* @__PURE__ */ jsx("div", { className: tabs ? "max-md:hidden" : void 0, children: /* @__PURE__ */ jsx(SideNav, { groups, onNavigate: () => setOpen(false) }) }),
1462
- footer ? /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer }) : null
1463
- ] })
1464
- ] }),
1465
- /* @__PURE__ */ jsx(Link5, { href: home, "aria-label": "Home", className: "rounded-lg p-1", children: /* @__PURE__ */ jsx(Lockup, { size: 22 }) }),
1466
- /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center", children: account })
1467
- ] }),
1468
- place.page ? /* @__PURE__ */ jsxs(
1469
- "div",
1470
- {
1471
- className: cn(
1472
- "flex h-9 items-center gap-1.5 border-t border-border px-4 text-[0.875rem]",
1473
- // The active tab already names the page.
1474
- tabs && !pageOverride && "max-md:hidden"
1475
- ),
1476
- children: [
1477
- place.section ? /* @__PURE__ */ jsxs(Fragment, { children: [
1478
- /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: place.section }),
1479
- /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-muted-foreground" })
1480
- ] }) : null,
1481
- /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: place.page })
1482
- ]
1483
- }
1484
- ) : null
1485
- ] }),
1486
- /* @__PURE__ */ jsxs("div", { className: "mx-auto flex w-full max-w-[90rem]", children: [
1487
- /* @__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: [
1488
- /* @__PURE__ */ jsx(Link5, { href: home, className: "px-2", "aria-label": "Home", children: /* @__PURE__ */ jsx(Lockup, { size: 26 }) }),
1489
- switcher,
1490
- /* @__PURE__ */ jsx(SideNav, { groups }),
1491
- /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer })
1492
- ] }),
1493
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
1494
- /* @__PURE__ */ jsx("div", { className: "hidden h-[4.5rem] items-center justify-end gap-3 px-8 lg:flex", children: account }),
1495
- banner ? /* @__PURE__ */ jsx("div", { className: "px-4 pb-2 pt-4 md:px-8 lg:pt-0", children: banner }) : null,
1496
- /* @__PURE__ */ jsx("main", { id: "main-content", className: "flex-1 px-4 pb-16 pt-6 md:px-8 lg:pt-2", children: /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-[72rem]", children }) })
1497
- ] })
1498
- ] }),
1499
- tabs ? /* @__PURE__ */ jsx(TabBar, { items: tabs }) : null
1500
- ]
1551
+ const [menu, setMenu] = useState(false);
1552
+ useEffect(() => setMenu(false), [current]);
1553
+ const read = useHeadings("#docs-content", current);
1554
+ const items = toc ?? read.items;
1555
+ const activeId = toc ? void 0 : read.activeId;
1556
+ const marked = navCurrent ?? current;
1557
+ const here = pathOf(marked);
1558
+ const place = useMemo(() => {
1559
+ for (const s of nav) {
1560
+ const it = s.items.find((i) => pathOf(i.href) === here);
1561
+ if (it) return { section: s.label, page: it.label };
1501
1562
  }
1502
- ) });
1503
- }
1504
- function AccountMenu({
1505
- name,
1506
- detail,
1507
- items,
1508
- nameFrom = "sm"
1509
- }) {
1510
- const initial = name.trim().charAt(0).toUpperCase() || "\xB7";
1511
- return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
1512
- /* @__PURE__ */ jsxs(
1513
- DropdownMenuTrigger,
1514
- {
1515
- className: cn(
1516
- "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",
1517
- nameFrom === "lg" ? "lg:pr-3.5" : "sm:pr-3.5"
1518
- ),
1519
- "aria-label": `${name}, account menu`,
1520
- children: [
1521
- /* @__PURE__ */ jsx(
1522
- "span",
1523
- {
1524
- "aria-hidden": true,
1525
- "data-initial": initial,
1526
- className: "flex size-8 items-center justify-center rounded-full bg-foreground text-[0.8125rem] font-medium text-background before:content-[attr(data-initial)]"
1527
- }
1528
- ),
1529
- /* @__PURE__ */ jsx("span", { className: cn("max-w-[10rem] truncate", nameFrom === "lg" ? "max-lg:hidden" : "max-sm:hidden"), children: name })
1530
- ]
1531
- }
1532
- ),
1533
- /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-64", children: [
1534
- /* @__PURE__ */ jsxs(DropdownMenuLabel, { className: "flex flex-col gap-0.5", children: [
1535
- /* @__PURE__ */ jsx("span", { className: "truncate text-[0.9375rem] font-medium text-foreground", children: name }),
1536
- detail ? /* @__PURE__ */ jsx("span", { className: "truncate font-mono text-[0.75rem]", children: detail }) : null
1563
+ return null;
1564
+ }, [nav, here]);
1565
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-h-dvh flex-col bg-background", children: [
1566
+ /* @__PURE__ */ jsx(SkipLink, {}),
1567
+ header ?? /* @__PURE__ */ jsx(SiteHeader, { home: OCHK_IO, family: "docs", nav: DOCS_HEADER_NAV, search, actions }),
1568
+ /* @__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: [
1569
+ /* @__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: [
1570
+ /* @__PURE__ */ jsx(PanelLeft, { "aria-hidden": true, className: "size-[1.125rem] shrink-0" }),
1571
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Docs menu. " }),
1572
+ place ? /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1573
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: place.section }),
1574
+ /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-oca-subtle" }),
1575
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: place.page })
1576
+ ] }) : /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Docs" })
1537
1577
  ] }),
1538
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
1539
- items.map(
1540
- (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: [
1541
- it.icon,
1542
- it.label
1543
- ] }) }, it.label) : /* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: it.onSelect, destructive: it.destructive, children: [
1544
- it.icon,
1545
- it.label
1546
- ] }, it.label)
1547
- )
1548
- ] })
1578
+ /* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "w-[min(88vw,22rem)] gap-0 p-0", children: [
1579
+ /* @__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" }) }),
1580
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto p-3", children: /* @__PURE__ */ jsx(DocsNav, { sections: nav, current: marked, onNavigate: () => setMenu(false) }) })
1581
+ ] })
1582
+ ] }) }) }),
1583
+ /* @__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: [
1584
+ /* @__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: marked }) }),
1585
+ /* @__PURE__ */ jsxs("main", { id: "main-content", className: "min-w-0 pb-16 pt-6 md:pt-8", children: [
1586
+ breadcrumbs ? /* @__PURE__ */ jsx("div", { className: "mb-6 max-lg:hidden", children: breadcrumbs }) : null,
1587
+ items.length > 1 ? /* @__PURE__ */ jsxs("details", { className: "group mb-8 rounded-2xl border border-border bg-card xl:hidden", children: [
1588
+ /* @__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: [
1589
+ "On this page",
1590
+ /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true, className: "size-4 text-muted-foreground transition-transform group-open:rotate-180" })
1591
+ ] }),
1592
+ /* @__PURE__ */ jsx(OnThisPage, { items, activeId, title: null, className: "px-4 pb-4" })
1593
+ ] }) : null,
1594
+ /* @__PURE__ */ jsx("article", { id: "docs-content", className: "max-w-[46rem]", children: /* @__PURE__ */ jsx(InDocsContext.Provider, { value: true, children }) }),
1595
+ pager ? /* @__PURE__ */ jsx("div", { className: "mt-16 max-w-[46rem]", children: pager }) : null
1596
+ ] }),
1597
+ /* @__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 })
1598
+ ] }) }),
1599
+ footer ?? /* @__PURE__ */ jsx(OchkIoFooter, {})
1549
1600
  ] });
1550
1601
  }
1551
- function ThemeToggle({ className }) {
1552
- const { theme, setTheme } = useTheme();
1553
- const [mounted, setMounted] = useState(false);
1554
- useEffect(() => setMounted(true), []);
1555
- const current = mounted ? theme ?? "system" : "system";
1556
- const next = current === "light" ? "dark" : current === "dark" ? "system" : "light";
1557
- const Icon = current === "light" ? Sun : current === "dark" ? Moon : SunMoon;
1558
- return /* @__PURE__ */ jsx(
1559
- "button",
1560
- {
1561
- type: "button",
1562
- onClick: () => setTheme(next),
1563
- "aria-label": `Theme: ${current}. Switch to ${next}`,
1564
- title: `Theme: ${current}`,
1565
- className: cn(
1566
- "inline-flex size-10 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
1567
- className
1568
- ),
1569
- children: /* @__PURE__ */ jsx(Icon, { className: "size-[1.125rem]" })
1570
- }
1571
- );
1572
- }
1573
1602
  var OCHK_APP_ACCOUNT = "https://ochk.app/me/account";
1603
+ function onHistory(change) {
1604
+ window.addEventListener("popstate", change);
1605
+ return () => window.removeEventListener("popstate", change);
1606
+ }
1607
+ function herePath() {
1608
+ const { href, origin, pathname, search } = window.location;
1609
+ const path = pathname + search;
1610
+ return new URL(path, href).origin === origin ? path : "/";
1611
+ }
1612
+ function routePath(router) {
1613
+ if (!router || router.pathname.includes("[")) return null;
1614
+ return router.basePath && router.pathname === "/" ? router.basePath : router.basePath + router.pathname;
1615
+ }
1616
+ function useSignInHref(path) {
1617
+ const router = useRouter();
1618
+ const here = useSyncExternalStore(onHistory, herePath, () => routePath(router));
1619
+ if (!path) return void 0;
1620
+ return here ? `${path}?return_to=${encodeURIComponent(here)}` : path;
1621
+ }
1574
1622
  function SessionAccountView({
1575
1623
  state,
1576
1624
  name,
1577
1625
  detail,
1578
1626
  items = [],
1579
1627
  signInHref,
1628
+ signInPath,
1580
1629
  signInLabel = "Sign in",
1581
1630
  accountHref = OCHK_APP_ACCOUNT,
1582
1631
  onSignOut,
1583
1632
  nameFrom = "lg"
1584
1633
  }) {
1634
+ const inPlace = useSignInHref(signInPath);
1585
1635
  if (state === "in") {
1586
1636
  return /* @__PURE__ */ jsx(
1587
1637
  AccountMenu,
@@ -1604,13 +1654,13 @@ function SessionAccountView({
1604
1654
  }
1605
1655
  return (
1606
1656
  // No box of its own: it sits exactly where the signed-in chip will. While checking it is only unseen.
1607
- /* @__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 }) }) })
1657
+ /* @__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 ?? inPlace ?? "https://ochk.io/signin", children: signInLabel }) }) })
1608
1658
  );
1609
1659
  }
1610
1660
  function ToolShell({
1611
1661
  protocol: protocol2,
1612
1662
  tools,
1613
- home = "/",
1663
+ home,
1614
1664
  account,
1615
1665
  rail = false,
1616
1666
  railFooter,
@@ -1649,7 +1699,7 @@ function ToolShell({
1649
1699
  SiteHeader,
1650
1700
  {
1651
1701
  variant: "tool",
1652
- home,
1702
+ home: home ?? p.pageHref,
1653
1703
  product: p.label,
1654
1704
  family: protocol2,
1655
1705
  nav: tools.map((t) => ({ href: t.href, label: t.label, active: t.active })),
@@ -1685,6 +1735,6 @@ function ToolShell({
1685
1735
  ) });
1686
1736
  }
1687
1737
 
1688
- export { AccountMenu, AppShell, DOCS_HEADER_NAV, DocsNav, DocsShell, FamilyMenu, OCHK_APP_ACCOUNT, SessionAccountView, ShellContext, SignInFrame, SiteBanner, SiteFooter, SiteHeader, SkipLink, ThemeToggle, ToolShell, useShellPlace };
1738
+ export { AccountMenu, AppShell, DOCS_HEADER_NAV, DocsNav, DocsShell, FamilyMenu, OCHK_APP_ACCOUNT, OchkIoFooter, SessionAccountView, ShellContext, SignInFrame, SiteBanner, SiteFooter, SiteHeader, SkipLink, ThemeToggle, ToolShell, useShellPlace, useSignInHref };
1689
1739
  //# sourceMappingURL=chrome.mjs.map
1690
1740
  //# sourceMappingURL=chrome.mjs.map