@orangecheck/app-design 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ export { A as ApiRow, a as ApiTable, b as AppCard, c as AppCardProps, d as AppGr
7
7
  import { ExplorerKind, Network } from './format.mjs';
8
8
  import { j as ProtocolSlug } from './index-DmfyPYe5.mjs';
9
9
  import { S as Statement } from './status-badge-BJ9Sdsx8.mjs';
10
- export { A as AnchorState, a as AnchorStatus, b as ArtifactView, B as BlockCountdown, c as BlockHeight, C as ChosenFile, D as DropZone, F as FilterChips, d as FilterOption, e as FormSection, M as Meter, S as SectionStatus, f as StateBadge, g as StateDef, h as StateTone, T as ToolGrid, i as ToolItem, j as createStateBadge } from './tools-DFIxIj5p.mjs';
10
+ export { A as AnchorState, a as AnchorStatus, b as ArtifactView, B as BlockCountdown, c as BlockHeight, C as ChosenFile, D as DropZone, F as FilterChips, d as FilterOption, e as FormSection, M as Meter, S as SectionStatus, f as StateBadge, g as StateDef, h as StateTone, T as ToolGrid, i as ToolItem, j as createStateBadge } from './tools-Bg1gi2HO.mjs';
11
11
 
12
12
  declare function Eyebrow({ className, onInk, ...props }: HTMLAttributes<HTMLParagraphElement> & {
13
13
  onInk?: boolean;
@@ -609,6 +609,35 @@ declare function ErrorPage({ code, title, detail, actions, home, protocol, art,
609
609
  className?: string;
610
610
  }): react.JSX.Element;
611
611
 
612
+ declare function CountdownRing({ period, remaining, warnAt, size, showSeconds, className, }: {
613
+ period: number;
614
+ remaining?: number;
615
+ warnAt?: number;
616
+ size?: number;
617
+ showSeconds?: boolean;
618
+ className?: string;
619
+ }): react.JSX.Element;
620
+ declare function PlanCard({ name, subtitle, price, period, footnote, features, action, badge, badgeTone, highlight, className, }: {
621
+ name: ReactNode;
622
+ subtitle?: ReactNode;
623
+ price: ReactNode;
624
+ period?: ReactNode;
625
+ footnote?: ReactNode;
626
+ features?: ReactNode[];
627
+ action?: ReactNode;
628
+ badge?: ReactNode;
629
+ badgeTone?: 'neutral' | 'brand' | 'success' | 'muted';
630
+ highlight?: boolean;
631
+ className?: string;
632
+ }): react.JSX.Element;
633
+ declare function LockedPreview({ title, description, action, children, className, }: {
634
+ title: ReactNode;
635
+ description?: ReactNode;
636
+ action: ReactNode;
637
+ children?: ReactNode;
638
+ className?: string;
639
+ }): react.JSX.Element;
640
+
612
641
  declare function SectionHeading({ eyebrow, title, lead, id, onInk, level, as, align, reveal, className, }: {
613
642
  eyebrow?: ReactNode;
614
643
  title: ReactNode;
@@ -758,7 +787,10 @@ declare function TextLink({ href: written, children, external, className, }: {
758
787
 
759
788
  interface SearchResult {
760
789
  id: string;
761
- href: string;
790
+ href?: string;
791
+ run?: () => void;
792
+ icon?: ReactNode;
793
+ meta?: ReactNode;
762
794
  title: ReactNode;
763
795
  section?: ReactNode;
764
796
  excerpt?: ReactNode;
@@ -774,7 +806,7 @@ declare const SearchButton: react.ForwardRefExoticComponent<{
774
806
  onClick?: () => void;
775
807
  className?: string;
776
808
  } & react.RefAttributes<HTMLButtonElement>>;
777
- declare function SearchDialog({ onQuery, open: openProp, onOpenChange, onSelect, button, hotkey, label, placeholder, idle, defaultQuery, debounceMs, className, }: {
809
+ interface SearchDialogProps {
778
810
  onQuery: SearchQuery;
779
811
  open?: boolean;
780
812
  onOpenChange?: (open: boolean) => void;
@@ -787,6 +819,9 @@ declare function SearchDialog({ onQuery, open: openProp, onOpenChange, onSelect,
787
819
  defaultQuery?: string;
788
820
  debounceMs?: number;
789
821
  className?: string;
790
- }): react.JSX.Element;
822
+ browse?: boolean;
823
+ }
824
+ declare function SearchDialog({ onQuery, open: openProp, onOpenChange, onSelect, button, hotkey, label, placeholder, idle, defaultQuery, debounceMs, browse, className, }: SearchDialogProps): react.JSX.Element;
825
+ declare function CommandDialog({ label, placeholder, ...props }: Omit<SearchDialogProps, 'browse' | 'button'>): react.JSX.Element;
791
826
 
792
- export { Accent, type ActivityItem, ActivityList, BrowserFrame, type CheckState, Closing, type Column, Container, CopyButton, type CopyButtonProps, DataTable, Display, type DisplayProps, EmptyLine, EmptyState, type Endpoint, EndpointList, ErrorBoundary, ErrorPage, Eyebrow, FactBlock, type FactRow, FactRows, Faq, FloatChip, Footnote, HashChip, type KeyValueItem, KeyValueList, Lead, type LegalBlock, LegalDocument, type LegalSource, LoadingBlock, Monogram, Notice, PackageCard, type PackageItem, PageHeader, PhoneFrame, type ProgressStep, ProgressSteps, ProofStrip, Prose, Reveal, Sats, SatsFigure, type SatsProps, type SatsTextOptions, ScrollStory, SearchButton, SearchDialog, type SearchGroup, type SearchQuery, type SearchResult, Section, SectionHeading, SectionIntro, type SectionProps, SignMessage, SplitBar, type SplitSegment, StatCard, type StatCardProps, StatGrid, type StatGridProps, StepGrid, type StepGridProps, type StepItem, type StepState, TextLink, Ticker, type TruthRow, type TruthStatus, TruthTable, UsdApprox, type VerifyCheck, VerifyReport, monogramGround, monogramLetter, satsText, sectionVariants, useCopy, useInView };
827
+ export { Accent, type ActivityItem, ActivityList, BrowserFrame, type CheckState, Closing, type Column, CommandDialog, Container, CopyButton, type CopyButtonProps, CountdownRing, DataTable, Display, type DisplayProps, EmptyLine, EmptyState, type Endpoint, EndpointList, ErrorBoundary, ErrorPage, Eyebrow, FactBlock, type FactRow, FactRows, Faq, FloatChip, Footnote, HashChip, type KeyValueItem, KeyValueList, Lead, type LegalBlock, LegalDocument, type LegalSource, LoadingBlock, LockedPreview, Monogram, Notice, PackageCard, type PackageItem, PageHeader, PhoneFrame, PlanCard, type ProgressStep, ProgressSteps, ProofStrip, Prose, Reveal, Sats, SatsFigure, type SatsProps, type SatsTextOptions, ScrollStory, SearchButton, SearchDialog, type SearchDialogProps, type SearchGroup, type SearchQuery, type SearchResult, Section, SectionHeading, SectionIntro, type SectionProps, SignMessage, SplitBar, type SplitSegment, StatCard, type StatCardProps, StatGrid, type StatGridProps, StepGrid, type StepGridProps, type StepItem, type StepState, TextLink, Ticker, type TruthRow, type TruthStatus, TruthTable, UsdApprox, type VerifyCheck, VerifyReport, monogramGround, monogramLetter, satsText, sectionVariants, useCopy, useInView };
@@ -7,7 +7,7 @@ export { A as ApiRow, a as ApiTable, b as AppCard, c as AppCardProps, d as AppGr
7
7
  import { ExplorerKind, Network } from './format.js';
8
8
  import { j as ProtocolSlug } from './index-DmfyPYe5.js';
9
9
  import { S as Statement } from './status-badge-Bt8x3RhO.js';
10
- export { A as AnchorState, a as AnchorStatus, b as ArtifactView, B as BlockCountdown, c as BlockHeight, C as ChosenFile, D as DropZone, F as FilterChips, d as FilterOption, e as FormSection, M as Meter, S as SectionStatus, f as StateBadge, g as StateDef, h as StateTone, T as ToolGrid, i as ToolItem, j as createStateBadge } from './tools-BggNN5DV.js';
10
+ export { A as AnchorState, a as AnchorStatus, b as ArtifactView, B as BlockCountdown, c as BlockHeight, C as ChosenFile, D as DropZone, F as FilterChips, d as FilterOption, e as FormSection, M as Meter, S as SectionStatus, f as StateBadge, g as StateDef, h as StateTone, T as ToolGrid, i as ToolItem, j as createStateBadge } from './tools-Bw7RhO92.js';
11
11
 
12
12
  declare function Eyebrow({ className, onInk, ...props }: HTMLAttributes<HTMLParagraphElement> & {
13
13
  onInk?: boolean;
@@ -609,6 +609,35 @@ declare function ErrorPage({ code, title, detail, actions, home, protocol, art,
609
609
  className?: string;
610
610
  }): react.JSX.Element;
611
611
 
612
+ declare function CountdownRing({ period, remaining, warnAt, size, showSeconds, className, }: {
613
+ period: number;
614
+ remaining?: number;
615
+ warnAt?: number;
616
+ size?: number;
617
+ showSeconds?: boolean;
618
+ className?: string;
619
+ }): react.JSX.Element;
620
+ declare function PlanCard({ name, subtitle, price, period, footnote, features, action, badge, badgeTone, highlight, className, }: {
621
+ name: ReactNode;
622
+ subtitle?: ReactNode;
623
+ price: ReactNode;
624
+ period?: ReactNode;
625
+ footnote?: ReactNode;
626
+ features?: ReactNode[];
627
+ action?: ReactNode;
628
+ badge?: ReactNode;
629
+ badgeTone?: 'neutral' | 'brand' | 'success' | 'muted';
630
+ highlight?: boolean;
631
+ className?: string;
632
+ }): react.JSX.Element;
633
+ declare function LockedPreview({ title, description, action, children, className, }: {
634
+ title: ReactNode;
635
+ description?: ReactNode;
636
+ action: ReactNode;
637
+ children?: ReactNode;
638
+ className?: string;
639
+ }): react.JSX.Element;
640
+
612
641
  declare function SectionHeading({ eyebrow, title, lead, id, onInk, level, as, align, reveal, className, }: {
613
642
  eyebrow?: ReactNode;
614
643
  title: ReactNode;
@@ -758,7 +787,10 @@ declare function TextLink({ href: written, children, external, className, }: {
758
787
 
759
788
  interface SearchResult {
760
789
  id: string;
761
- href: string;
790
+ href?: string;
791
+ run?: () => void;
792
+ icon?: ReactNode;
793
+ meta?: ReactNode;
762
794
  title: ReactNode;
763
795
  section?: ReactNode;
764
796
  excerpt?: ReactNode;
@@ -774,7 +806,7 @@ declare const SearchButton: react.ForwardRefExoticComponent<{
774
806
  onClick?: () => void;
775
807
  className?: string;
776
808
  } & react.RefAttributes<HTMLButtonElement>>;
777
- declare function SearchDialog({ onQuery, open: openProp, onOpenChange, onSelect, button, hotkey, label, placeholder, idle, defaultQuery, debounceMs, className, }: {
809
+ interface SearchDialogProps {
778
810
  onQuery: SearchQuery;
779
811
  open?: boolean;
780
812
  onOpenChange?: (open: boolean) => void;
@@ -787,6 +819,9 @@ declare function SearchDialog({ onQuery, open: openProp, onOpenChange, onSelect,
787
819
  defaultQuery?: string;
788
820
  debounceMs?: number;
789
821
  className?: string;
790
- }): react.JSX.Element;
822
+ browse?: boolean;
823
+ }
824
+ declare function SearchDialog({ onQuery, open: openProp, onOpenChange, onSelect, button, hotkey, label, placeholder, idle, defaultQuery, debounceMs, browse, className, }: SearchDialogProps): react.JSX.Element;
825
+ declare function CommandDialog({ label, placeholder, ...props }: Omit<SearchDialogProps, 'browse' | 'button'>): react.JSX.Element;
791
826
 
792
- export { Accent, type ActivityItem, ActivityList, BrowserFrame, type CheckState, Closing, type Column, Container, CopyButton, type CopyButtonProps, DataTable, Display, type DisplayProps, EmptyLine, EmptyState, type Endpoint, EndpointList, ErrorBoundary, ErrorPage, Eyebrow, FactBlock, type FactRow, FactRows, Faq, FloatChip, Footnote, HashChip, type KeyValueItem, KeyValueList, Lead, type LegalBlock, LegalDocument, type LegalSource, LoadingBlock, Monogram, Notice, PackageCard, type PackageItem, PageHeader, PhoneFrame, type ProgressStep, ProgressSteps, ProofStrip, Prose, Reveal, Sats, SatsFigure, type SatsProps, type SatsTextOptions, ScrollStory, SearchButton, SearchDialog, type SearchGroup, type SearchQuery, type SearchResult, Section, SectionHeading, SectionIntro, type SectionProps, SignMessage, SplitBar, type SplitSegment, StatCard, type StatCardProps, StatGrid, type StatGridProps, StepGrid, type StepGridProps, type StepItem, type StepState, TextLink, Ticker, type TruthRow, type TruthStatus, TruthTable, UsdApprox, type VerifyCheck, VerifyReport, monogramGround, monogramLetter, satsText, sectionVariants, useCopy, useInView };
827
+ export { Accent, type ActivityItem, ActivityList, BrowserFrame, type CheckState, Closing, type Column, CommandDialog, Container, CopyButton, type CopyButtonProps, CountdownRing, DataTable, Display, type DisplayProps, EmptyLine, EmptyState, type Endpoint, EndpointList, ErrorBoundary, ErrorPage, Eyebrow, FactBlock, type FactRow, FactRows, Faq, FloatChip, Footnote, HashChip, type KeyValueItem, KeyValueList, Lead, type LegalBlock, LegalDocument, type LegalSource, LoadingBlock, LockedPreview, Monogram, Notice, PackageCard, type PackageItem, PageHeader, PhoneFrame, PlanCard, type ProgressStep, ProgressSteps, ProofStrip, Prose, Reveal, Sats, SatsFigure, type SatsProps, type SatsTextOptions, ScrollStory, SearchButton, SearchDialog, type SearchDialogProps, type SearchGroup, type SearchQuery, type SearchResult, Section, SectionHeading, SectionIntro, type SectionProps, SignMessage, SplitBar, type SplitSegment, StatCard, type StatCardProps, StatGrid, type StatGridProps, StepGrid, type StepGridProps, type StepItem, type StepState, TextLink, Ticker, type TruthRow, type TruthStatus, TruthTable, UsdApprox, type VerifyCheck, VerifyReport, monogramGround, monogramLetter, satsText, sectionVariants, useCopy, useInView };
@@ -564,7 +564,7 @@ var JS_TAG = /<\/?(?=[A-Za-z])/y;
564
564
  var JS_TAG_NAME = /[A-Za-z][\w$.:-]*/y;
565
565
  var JS_PUNCT = /=>|\.\.\.|[{}()[\];,.<>=+\-*/%!?:&|^~#]/y;
566
566
  var JSX_BEFORE = /* @__PURE__ */ new Set(["(", ",", "=", "?", ":", "{", "[", ";", ">", "&&", "||", "=>", "return"]);
567
- function scanJs(src, emit, jsx35) {
567
+ function scanJs(src, emit, jsx36) {
568
568
  let i = 0;
569
569
  let prev = "";
570
570
  let tagDepth = 0;
@@ -590,7 +590,7 @@ function scanJs(src, emit, jsx35) {
590
590
  sig('"');
591
591
  continue;
592
592
  }
593
- if (jsx35 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
593
+ if (jsx36 && tagDepth === 0 && (m = at(JS_TAG, src, i)) && (prev === "" || JSX_BEFORE.has(prev))) {
594
594
  const name = at(JS_TAG_NAME, src, i + m.length);
595
595
  if (name) {
596
596
  emit(m);
@@ -602,7 +602,7 @@ function scanJs(src, emit, jsx35) {
602
602
  continue;
603
603
  }
604
604
  }
605
- if (jsx35 && tagDepth > 0 && braceInTag === 0) {
605
+ if (jsx36 && tagDepth > 0 && braceInTag === 0) {
606
606
  if (src.startsWith("/>", i) || src[i] === ">") {
607
607
  const close = src[i] === ">" ? ">" : "/>";
608
608
  emit(close);
@@ -622,7 +622,7 @@ function scanJs(src, emit, jsx35) {
622
622
  continue;
623
623
  }
624
624
  if (src[i] === "{") braceInTag = 1;
625
- } else if (jsx35 && tagDepth > 0 && braceInTag > 0) {
625
+ } else if (jsx36 && tagDepth > 0 && braceInTag > 0) {
626
626
  if (src[i] === "{") braceInTag++;
627
627
  else if (src[i] === "}") braceInTag--;
628
628
  }
@@ -2506,6 +2506,131 @@ function ErrorPage({
2506
2506
  art !== null ? /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, className: "oca-enter hidden justify-center md:col-span-5 md:flex [--enter-delay:120ms]", children: art ?? /* @__PURE__ */ jsxRuntime.jsx(MarkOutline, { className: "w-full max-w-[20rem] text-oca-hairline-strong" }) }) : null
2507
2507
  ] }) });
2508
2508
  }
2509
+ function onSecond(tick) {
2510
+ const id = setInterval(tick, 1e3);
2511
+ return () => clearInterval(id);
2512
+ }
2513
+ var nowSeconds = () => Math.floor(Date.now() / 1e3);
2514
+ function CountdownRing({
2515
+ period,
2516
+ remaining,
2517
+ warnAt = 5,
2518
+ size = 18,
2519
+ showSeconds = true,
2520
+ className
2521
+ }) {
2522
+ const now = react.useSyncExternalStore(onSecond, nowSeconds, () => null);
2523
+ const left = remaining ?? (now === null ? null : period - now % period);
2524
+ const share = left === null ? 1 : Math.max(0, Math.min(1, left / period));
2525
+ const warn = left !== null && left <= warnAt;
2526
+ const r = size / 2 - 1.5;
2527
+ const c = 2 * Math.PI * r;
2528
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2529
+ "span",
2530
+ {
2531
+ role: "timer",
2532
+ "aria-label": left === null ? void 0 : `${left} second${left === 1 ? "" : "s"} left`,
2533
+ className: cn("inline-flex items-center gap-1.5", warn ? "text-destructive" : "text-muted-foreground", className),
2534
+ children: [
2535
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { "aria-hidden": true, width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", children: [
2536
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: size / 2, cy: size / 2, r, fill: "none", stroke: "var(--border)", strokeWidth: 2 }),
2537
+ /* @__PURE__ */ jsxRuntime.jsx(
2538
+ "circle",
2539
+ {
2540
+ cx: size / 2,
2541
+ cy: size / 2,
2542
+ r,
2543
+ fill: "none",
2544
+ stroke: "currentColor",
2545
+ strokeWidth: 2,
2546
+ strokeLinecap: "round",
2547
+ strokeDasharray: c,
2548
+ strokeDashoffset: c * (1 - share),
2549
+ className: cn(left !== null && left < period && "transition-[stroke-dashoffset] duration-1000 ease-linear motion-reduce:transition-none")
2550
+ }
2551
+ )
2552
+ ] }),
2553
+ showSeconds && left !== null ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[0.8125rem] oca-tabular", children: [
2554
+ left,
2555
+ "s"
2556
+ ] }) : null
2557
+ ]
2558
+ }
2559
+ );
2560
+ }
2561
+ function PlanCard({
2562
+ name,
2563
+ subtitle,
2564
+ price,
2565
+ period,
2566
+ footnote,
2567
+ features = [],
2568
+ action,
2569
+ badge,
2570
+ badgeTone = "neutral",
2571
+ highlight: highlight2 = false,
2572
+ className
2573
+ }) {
2574
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2575
+ "section",
2576
+ {
2577
+ className: cn(
2578
+ "flex h-full flex-col gap-5 rounded-[1.25rem] border bg-card p-6",
2579
+ highlight2 ? "border-foreground shadow-sm ring-1 ring-foreground" : "border-border",
2580
+ className
2581
+ ),
2582
+ children: [
2583
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
2584
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
2585
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[1.0625rem] font-medium leading-snug", children: name }),
2586
+ badge ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: badgeTone, children: badge }) : null
2587
+ ] }),
2588
+ subtitle ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] leading-snug text-muted-foreground", children: subtitle }) : null
2589
+ ] }),
2590
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
2591
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "flex flex-wrap items-baseline gap-x-1.5", children: [
2592
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oca-display-3 oca-tabular", children: price }),
2593
+ period ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.9375rem] text-muted-foreground", children: period }) : null
2594
+ ] }),
2595
+ footnote ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.8125rem] text-muted-foreground", children: footnote }) : null
2596
+ ] }),
2597
+ features.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-2.5 text-[0.9375rem]", children: features.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start gap-2.5", children: [
2598
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { "aria-hidden": true, className: "mt-1 size-4 shrink-0 text-muted-foreground" }),
2599
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0", children: f })
2600
+ ] }, i)) }) : null,
2601
+ action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col pt-1 [&>*]:w-full", children: action }) : null
2602
+ ]
2603
+ }
2604
+ );
2605
+ }
2606
+ function LockedPreview({
2607
+ title,
2608
+ description,
2609
+ action,
2610
+ children,
2611
+ className
2612
+ }) {
2613
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", className), children: [
2614
+ children ? /* @__PURE__ */ jsxRuntime.jsx(
2615
+ "div",
2616
+ {
2617
+ inert: true,
2618
+ "aria-hidden": true,
2619
+ "data-oca-locked": "",
2620
+ className: "pointer-events-none max-h-[28rem] select-none overflow-hidden [mask-image:linear-gradient(to_bottom,#000_25%,transparent_85%)]",
2621
+ children
2622
+ }
2623
+ ) : null,
2624
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative mx-auto flex max-w-md flex-col items-center gap-4 rounded-[1.25rem] border border-border bg-card px-6 py-7 text-center shadow-sm", children && "-mt-40"), children: [
2625
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "flex size-10 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { className: "size-[1.125rem]" }) }),
2626
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
2627
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[1.0625rem] font-medium leading-snug", children: title }),
2628
+ description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.9375rem] leading-snug text-muted-foreground", children: description }) : null
2629
+ ] }),
2630
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-2", children: action })
2631
+ ] })
2632
+ ] });
2633
+ }
2509
2634
  function IsoCheck({ size = 360, settle = false, shadow = true, tilt = false, title, className }) {
2510
2635
  const ref = react.useRef(null);
2511
2636
  react.useEffect(() => {
@@ -3966,6 +4091,7 @@ function SearchDialog({
3966
4091
  idle,
3967
4092
  defaultQuery = "",
3968
4093
  debounceMs = 120,
4094
+ browse = false,
3969
4095
  className
3970
4096
  }) {
3971
4097
  const [own, setOwn] = react.useState(false);
@@ -4002,7 +4128,7 @@ function SearchDialog({
4002
4128
  }, [hotkey]);
4003
4129
  react.useEffect(() => {
4004
4130
  const q = query.trim();
4005
- if (!q) {
4131
+ if (!q && !(browse && open)) {
4006
4132
  setGroups([]);
4007
4133
  setState("idle");
4008
4134
  return;
@@ -4024,14 +4150,15 @@ function SearchDialog({
4024
4150
  clearTimeout(t);
4025
4151
  ctl.abort();
4026
4152
  };
4027
- }, [query, debounceMs]);
4153
+ }, [query, debounceMs, browse, open]);
4028
4154
  react.useEffect(() => {
4029
4155
  listRef.current?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
4030
4156
  }, [active]);
4031
4157
  const choose = (r) => {
4032
4158
  setOpen(false);
4033
- if (onSelect) onSelect(r);
4034
- else window.location.assign(r.href);
4159
+ if (r.run) r.run();
4160
+ else if (onSelect) onSelect(r);
4161
+ else if (r.href) window.location.assign(r.href);
4035
4162
  };
4036
4163
  const optionId = (i) => `${listId}-o${i}`;
4037
4164
  const showList = state === "done" && flat.length > 0;
@@ -4102,25 +4229,28 @@ function SearchDialog({
4102
4229
  index++;
4103
4230
  const i = index;
4104
4231
  const on = i === active;
4232
+ const Option = r.href ? "a" : "div";
4105
4233
  return /* @__PURE__ */ jsxRuntime.jsxs(
4106
- "a",
4234
+ Option,
4107
4235
  {
4108
4236
  id: optionId(i),
4109
- href: r.href,
4237
+ ...r.href ? { href: r.href } : {},
4110
4238
  role: "option",
4111
4239
  "aria-selected": on,
4112
4240
  tabIndex: -1,
4113
4241
  onMouseMove: () => setActive(i),
4114
4242
  onClick: (e) => {
4115
- if (e.metaKey || e.ctrlKey || e.shiftKey) return;
4243
+ if (r.href && (e.metaKey || e.ctrlKey || e.shiftKey)) return;
4116
4244
  e.preventDefault();
4117
4245
  choose(r);
4118
4246
  },
4119
4247
  className: cn(
4120
4248
  "flex items-start gap-3 rounded-xl px-3 py-2.5 transition-colors",
4121
- on ? "bg-accent" : "hover:bg-accent"
4249
+ on ? "bg-accent" : "hover:bg-accent",
4250
+ !r.href && "cursor-pointer"
4122
4251
  ),
4123
4252
  children: [
4253
+ r.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "mt-0.5 flex size-5 shrink-0 items-center justify-center text-muted-foreground [&_svg]:size-[1.0625rem]", children: r.icon }) : null,
4124
4254
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
4125
4255
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.9375rem] font-medium text-foreground", children: r.title }),
4126
4256
  r.section ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[0.8125rem] text-muted-foreground", children: r.section }) : null,
@@ -4132,6 +4262,7 @@ function SearchDialog({
4132
4262
  }
4133
4263
  ) : r.excerpt ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-2 text-[0.875rem] leading-snug text-muted-foreground", children: r.excerpt }) : null
4134
4264
  ] }),
4265
+ r.meta ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 shrink-0 text-[0.8125rem] text-muted-foreground", children: r.meta }) : null,
4135
4266
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownLeft, { "aria-hidden": true, className: cn("mt-1 size-4 shrink-0 text-muted-foreground", !on && "invisible") })
4136
4267
  ]
4137
4268
  },
@@ -4140,11 +4271,11 @@ function SearchDialog({
4140
4271
  })
4141
4272
  ] }, gi)) }),
4142
4273
  state === "idle" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: idle ?? "Type a word: a protocol, a function, an error." }) : null,
4143
- state === "done" && flat.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: [
4274
+ state === "done" && flat.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: query.trim() ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4144
4275
  "No results for \u201C",
4145
4276
  query.trim(),
4146
4277
  "\u201D."
4147
- ] }) : null,
4278
+ ] }) : "Nothing here yet." }) : null,
4148
4279
  state === "error" ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: "px-3 py-6 text-[0.9375rem] text-muted-foreground", children: "Search is not available right now. Try again in a moment." }) : null
4149
4280
  ] }),
4150
4281
  /* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-hidden": true, className: "hidden shrink-0 items-center gap-4 border-t border-border px-5 py-2.5 text-[0.75rem] text-muted-foreground sm:flex", children: [
@@ -4169,6 +4300,13 @@ function SearchDialog({
4169
4300
  ] }) })
4170
4301
  ] });
4171
4302
  }
4303
+ function CommandDialog({
4304
+ label = "Commands",
4305
+ placeholder = "Search, or run a command",
4306
+ ...props
4307
+ }) {
4308
+ return /* @__PURE__ */ jsxRuntime.jsx(SearchDialog, { ...props, label, placeholder, button: false, browse: true });
4309
+ }
4172
4310
  function pretty(content) {
4173
4311
  try {
4174
4312
  return JSON.stringify(JSON.parse(content), null, 2);
@@ -4597,6 +4735,13 @@ function BlockCountdown({
4597
4735
  ] }) : null
4598
4736
  ] });
4599
4737
  }
4738
+ var METER_FILL = {
4739
+ ink: "bg-foreground",
4740
+ brand: "bg-oca-orange-deep",
4741
+ good: "bg-success",
4742
+ caution: "bg-warning",
4743
+ bad: "bg-destructive"
4744
+ };
4600
4745
  function Meter({
4601
4746
  value,
4602
4747
  max,
@@ -4631,7 +4776,7 @@ function Meter({
4631
4776
  /* @__PURE__ */ jsxRuntime.jsx(
4632
4777
  "div",
4633
4778
  {
4634
- className: cn("h-full shrink-0 rounded-full", tone === "brand" ? "bg-oca-orange-deep" : "bg-foreground"),
4779
+ className: cn("h-full shrink-0 rounded-full", METER_FILL[tone]),
4635
4780
  style: { width: `${v * 100}%` }
4636
4781
  }
4637
4782
  ),
@@ -4761,9 +4906,11 @@ exports.CardGrid = CardGrid;
4761
4906
  exports.Closing = Closing;
4762
4907
  exports.CodeBlock = CodeBlock;
4763
4908
  exports.CodeTabs = CodeTabs;
4909
+ exports.CommandDialog = CommandDialog;
4764
4910
  exports.ComparisonTable = ComparisonTable;
4765
4911
  exports.Container = Container;
4766
4912
  exports.CopyButton = CopyButton;
4913
+ exports.CountdownRing = CountdownRing;
4767
4914
  exports.DataTable = DataTable;
4768
4915
  exports.Diagram = Diagram;
4769
4916
  exports.Display = Display;
@@ -4792,6 +4939,7 @@ exports.Lead = Lead;
4792
4939
  exports.LegalDocument = LegalDocument;
4793
4940
  exports.LinkCard = LinkCard;
4794
4941
  exports.LoadingBlock = LoadingBlock;
4942
+ exports.LockedPreview = LockedPreview;
4795
4943
  exports.MdxTable = MdxTable;
4796
4944
  exports.Meter = Meter;
4797
4945
  exports.Monogram = Monogram;
@@ -4801,6 +4949,7 @@ exports.PackageCard = PackageCard;
4801
4949
  exports.PageHeader = PageHeader;
4802
4950
  exports.PageHero = PageHero;
4803
4951
  exports.PhoneFrame = PhoneFrame;
4952
+ exports.PlanCard = PlanCard;
4804
4953
  exports.ProgressSteps = ProgressSteps;
4805
4954
  exports.ProofStrip = ProofStrip;
4806
4955
  exports.Prose = Prose;