@estiva-app/ui 0.74.1 → 0.75.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 (67) hide show
  1. package/dist/CardUnder.d.ts +10 -0
  2. package/dist/CardUnder.d.ts.map +1 -0
  3. package/dist/InlineChip.d.ts +2 -0
  4. package/dist/InlineChip.d.ts.map +1 -1
  5. package/dist/LinkCard.d.ts +17 -0
  6. package/dist/LinkCard.d.ts.map +1 -0
  7. package/dist/LinkChip.d.ts +8 -0
  8. package/dist/LinkChip.d.ts.map +1 -0
  9. package/dist/LinkParts.d.ts +45 -0
  10. package/dist/LinkParts.d.ts.map +1 -0
  11. package/dist/LinkPreview.d.ts +21 -0
  12. package/dist/LinkPreview.d.ts.map +1 -0
  13. package/dist/LinkRow.d.ts +24 -0
  14. package/dist/LinkRow.d.ts.map +1 -0
  15. package/dist/PartCard.d.ts +32 -0
  16. package/dist/PartCard.d.ts.map +1 -0
  17. package/dist/Skeleton.d.ts +12 -2
  18. package/dist/Skeleton.d.ts.map +1 -1
  19. package/dist/eslint/index.js +1 -0
  20. package/dist/eslint/index.js.map +2 -2
  21. package/dist/eslint/no-restyled-part.d.ts.map +1 -1
  22. package/dist/index.d.ts +8 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +480 -71
  25. package/dist/index.js.map +4 -4
  26. package/dist/linked.d.ts +168 -0
  27. package/dist/linked.d.ts.map +1 -0
  28. package/dist/linked.examples.d.ts +27 -0
  29. package/dist/linked.examples.d.ts.map +1 -0
  30. package/package.json +1 -1
  31. package/registry.json +784 -7
  32. package/src/CardUnder.mdx +53 -0
  33. package/src/CardUnder.stories.tsx +45 -0
  34. package/src/CardUnder.test.tsx +40 -0
  35. package/src/CardUnder.tsx +45 -0
  36. package/src/InlineChip.tsx +2 -0
  37. package/src/LinkCard.mdx +58 -0
  38. package/src/LinkCard.stories.tsx +68 -0
  39. package/src/LinkCard.test.tsx +103 -0
  40. package/src/LinkCard.tsx +209 -0
  41. package/src/LinkChip.mdx +51 -0
  42. package/src/LinkChip.stories.tsx +40 -0
  43. package/src/LinkChip.test.tsx +83 -0
  44. package/src/LinkChip.tsx +51 -0
  45. package/src/LinkParts.mdx +49 -0
  46. package/src/LinkParts.stories.tsx +61 -0
  47. package/src/LinkParts.tsx +147 -0
  48. package/src/LinkPreview.mdx +47 -0
  49. package/src/LinkPreview.stories.tsx +38 -0
  50. package/src/LinkPreview.tsx +55 -0
  51. package/src/LinkRow.mdx +47 -0
  52. package/src/LinkRow.stories.tsx +49 -0
  53. package/src/LinkRow.test.tsx +38 -0
  54. package/src/LinkRow.tsx +107 -0
  55. package/src/PartCard.mdx +43 -0
  56. package/src/PartCard.stories.tsx +35 -0
  57. package/src/PartCard.test.tsx +30 -0
  58. package/src/PartCard.tsx +59 -0
  59. package/src/Skeleton.tsx +7 -3
  60. package/src/eslint/no-native-title.test.ts +3 -2
  61. package/src/eslint/no-restyled-part.ts +1 -0
  62. package/src/index.ts +25 -0
  63. package/src/linked.examples.ts +107 -0
  64. package/src/linked.test.ts +58 -0
  65. package/src/linked.ts +217 -0
  66. package/src/registry/registry.test.ts +8 -8
  67. package/stories/Choosing.mdx +7 -0
package/dist/index.js CHANGED
@@ -2075,8 +2075,9 @@ function EmptyState({ icon, message, scope = "page", action, className }) {
2075
2075
 
2076
2076
  // src/Skeleton.tsx
2077
2077
  import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
2078
- function SkeletonBar({ className, style }) {
2079
- return /* @__PURE__ */ jsx31("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
2078
+ var SKELETON_SHAPE = { bar: "rounded-sm", round: "rounded-full", control: "rounded-md" };
2079
+ function SkeletonBar({ className, style, on = "surface", shape = "bar" }) {
2080
+ return /* @__PURE__ */ jsx31("div", { className: cn("animate-pulse", SKELETON_SHAPE[shape], on === "inset" ? "bg-bg-active" : "bg-bg-inset", className), style });
2080
2081
  }
2081
2082
  var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
2082
2083
  function SkeletonRow({ barWidth = 130 }) {
@@ -2416,7 +2417,9 @@ var INLINE_CHIP_TONE_CLASSES = {
2416
2417
  * baseline. At 19.6px they sit 0.4px off it (measured 2026-09-14; Peek's
2417
2418
  * copy of this chip still has the 16.8px box).
2418
2419
  */
2419
- quiet: "h-[19.6px] bg-bg-active text-text-muted font-mono text-caption"
2420
+ quiet: "h-[19.6px] bg-bg-active text-text-muted font-mono text-caption",
2421
+ /** A file this reader cannot open — deleted, or not theirs to see: said in words, quieter than a link. */
2422
+ muted: "bg-bg-active text-text-muted"
2420
2423
  };
2421
2424
  function inlineChipClassName(tone, className) {
2422
2425
  return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
@@ -4021,17 +4024,404 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
4021
4024
  ] });
4022
4025
  }
4023
4026
 
4027
+ // src/linked.ts
4028
+ function chosenOf(picker) {
4029
+ return picker?.value === void 0 ? void 0 : picker.options.find((option) => option.value === picker.value);
4030
+ }
4031
+ function loadingShapeOf(linked) {
4032
+ return {
4033
+ subtitle: !!(linked.subtitle || linked.key),
4034
+ summary: !!linked.summary,
4035
+ rows: linked.children?.length ?? 0,
4036
+ latest: !!linked.latest,
4037
+ ring: !!linked.done,
4038
+ footer: linked.status || linked.owner ? "pickers" : linked.authors ? "people" : "line"
4039
+ };
4040
+ }
4041
+ function unavailableMemory(storageKey, limit = 300) {
4042
+ let held;
4043
+ const list = () => {
4044
+ if (held) return held;
4045
+ try {
4046
+ const stored = JSON.parse(localStorage.getItem(storageKey) ?? "[]");
4047
+ held = new Set(Array.isArray(stored) ? stored.filter((item) => typeof item === "string") : []);
4048
+ } catch {
4049
+ held = /* @__PURE__ */ new Set();
4050
+ }
4051
+ return held;
4052
+ };
4053
+ return {
4054
+ has: (id) => list().has(id),
4055
+ note: (id, available) => {
4056
+ held = void 0;
4057
+ const current = list();
4058
+ if (available !== current.has(id)) return;
4059
+ const next = new Set(current);
4060
+ if (available) next.delete(id);
4061
+ else next.add(id);
4062
+ held = new Set([...next].slice(-limit));
4063
+ try {
4064
+ localStorage.setItem(storageKey, JSON.stringify([...held]));
4065
+ } catch {
4066
+ }
4067
+ },
4068
+ clear: () => {
4069
+ held = void 0;
4070
+ try {
4071
+ localStorage.removeItem(storageKey);
4072
+ } catch {
4073
+ }
4074
+ }
4075
+ };
4076
+ }
4077
+
4078
+ // src/LinkParts.tsx
4079
+ import { IconCircleCheck, IconCircleDashed as IconCircleDashed2, IconCircleHalf2, IconCircleX, IconFileText, IconMessage2 as IconMessage22 } from "@tabler/icons-react";
4080
+ import { jsx as jsx59, jsxs as jsxs40 } from "react/jsx-runtime";
4081
+ var STATUS_ICON = {
4082
+ neutral: { Icon: IconCircleDashed2, tone: "text-text-secondary" },
4083
+ blue: { Icon: IconCircleHalf2, tone: "text-info-default" },
4084
+ green: { Icon: IconCircleCheck, tone: "text-success-default" },
4085
+ muted: { Icon: IconCircleX, tone: "text-text-muted" }
4086
+ };
4087
+ function StatusIcon({ colour }) {
4088
+ const { Icon, tone } = STATUS_ICON[colour];
4089
+ return /* @__PURE__ */ jsx59(Icon, { size: 14, stroke: 1.5, className: cn("shrink-0", tone), "aria-hidden": true });
4090
+ }
4091
+ function StatusMark({ status }) {
4092
+ return /* @__PURE__ */ jsxs40(WithTooltip, { label: status.label, inline: true, wrapperClassName: "inline-flex shrink-0 items-center", children: [
4093
+ /* @__PURE__ */ jsx59(StatusIcon, { colour: status.colour }),
4094
+ /* @__PURE__ */ jsx59("span", { className: "sr-only", children: status.label })
4095
+ ] });
4096
+ }
4097
+ function LinkedIcon({ kind, size = 16, tone = "secondary" }) {
4098
+ if (kind === "page") return /* @__PURE__ */ jsx59(IconFileText, { size, stroke: 1.5, className: cn("shrink-0", tone === "secondary" && "text-text-secondary"), "aria-hidden": true });
4099
+ return /* @__PURE__ */ jsx59(KindIcon, { kind, size, tone });
4100
+ }
4101
+ function LinkKey({ children }) {
4102
+ return /* @__PURE__ */ jsx59("span", { className: "shrink-0 text-caption tabular-nums text-text-muted", children });
4103
+ }
4104
+ function ProgressRing({ done, total }) {
4105
+ const size = 16;
4106
+ const stroke = 2;
4107
+ const r = (size - stroke) / 2;
4108
+ const c = 2 * Math.PI * r;
4109
+ const share = total > 0 ? Math.min(done, total) / total : 0;
4110
+ return /* @__PURE__ */ jsx59(WithTooltip, { label: `${done} of ${total} done`, inline: true, wrapperClassName: "inline-flex shrink-0", children: /* @__PURE__ */ jsxs40("span", { className: "inline-flex shrink-0 items-center gap-1 text-caption tabular-nums text-text-secondary", children: [
4111
+ /* @__PURE__ */ jsxs40("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "shrink-0 -rotate-90", "aria-hidden": true, children: [
4112
+ /* @__PURE__ */ jsx59("circle", { cx: size / 2, cy: size / 2, r, fill: "none", strokeWidth: stroke, className: "stroke-border-default" }),
4113
+ /* @__PURE__ */ jsx59("circle", { cx: size / 2, cy: size / 2, r, fill: "none", strokeWidth: stroke, strokeLinecap: "round", strokeDasharray: `${c * share} ${c}`, className: "stroke-success-default" })
4114
+ ] }),
4115
+ done,
4116
+ "/",
4117
+ total
4118
+ ] }) });
4119
+ }
4120
+ function CommentCount({ conversation, noun = "comments" }) {
4121
+ const { count, href, unread = false } = conversation;
4122
+ return /* @__PURE__ */ jsx59("span", { className: cn("relative z-10 -mx-1 inline-flex shrink-0 rounded-sm px-1 text-caption tabular-nums hover:bg-bg-active", unread ? "font-medium text-text-primary" : "text-text-secondary"), children: /* @__PURE__ */ jsxs40(Link, { href, variant: "plain", className: "inline-flex items-center gap-1", children: [
4123
+ /* @__PURE__ */ jsx59(IconMessage22, { size: 14, stroke: 1.5, "aria-hidden": true }),
4124
+ count,
4125
+ /* @__PURE__ */ jsx59("span", { className: "sr-only", children: unread ? `${noun}, unread \u2014 open the conversation` : `${noun} \u2014 open the conversation` }),
4126
+ unread && /* @__PURE__ */ jsx59(UnreadDot, { className: "h-auto w-auto" })
4127
+ ] }) });
4128
+ }
4129
+ function LinkPickers({ status, owner, ownerLabel = "Owner", readOnly = false }) {
4130
+ const statusNow = chosenOf(status);
4131
+ const ownerNow = chosenOf(owner);
4132
+ const statusWords = status && (readOnly || !status.onChange);
4133
+ const ownerWords = owner && (readOnly || !owner.onChange);
4134
+ return /* @__PURE__ */ jsxs40("span", { className: "flex h-6 min-w-0 items-center gap-2 text-caption text-text-secondary", children: [
4135
+ status && (statusWords ? /* @__PURE__ */ jsxs40("span", { className: "inline-flex shrink-0 items-center gap-1", children: [
4136
+ statusNow?.colour && /* @__PURE__ */ jsx59(StatusIcon, { colour: statusNow.colour }),
4137
+ statusNow?.label ?? "No status"
4138
+ ] }) : /* @__PURE__ */ jsx59(
4139
+ Select,
4140
+ {
4141
+ size: "small",
4142
+ className: "w-auto",
4143
+ value: status.value ?? "",
4144
+ onChange: (value) => status.onChange?.(value),
4145
+ ariaLabel: "Status",
4146
+ options: status.options.map((option) => ({ value: option.value, label: option.label, leading: option.colour && /* @__PURE__ */ jsx59(StatusIcon, { colour: option.colour }) }))
4147
+ }
4148
+ )),
4149
+ owner && (ownerWords ? /* @__PURE__ */ jsxs40("span", { className: "inline-flex min-w-0 items-center gap-1", children: [
4150
+ /* @__PURE__ */ jsx59(Avatar, { name: ownerNow?.label, src: ownerNow?.picture, size: 16 }),
4151
+ /* @__PURE__ */ jsx59("span", { className: "truncate", children: ownerNow?.label ?? "Unassigned" })
4152
+ ] }) : /* @__PURE__ */ jsx59(
4153
+ Select,
4154
+ {
4155
+ size: "small",
4156
+ className: "w-auto",
4157
+ value: owner.value ?? "",
4158
+ placeholder: "Unassigned",
4159
+ onChange: (value) => owner.onChange?.(value),
4160
+ ariaLabel: ownerLabel,
4161
+ options: owner.options.map((option) => ({ value: option.value, label: option.label, leading: /* @__PURE__ */ jsx59(Avatar, { name: option.label, src: option.picture, size: 16 }) }))
4162
+ }
4163
+ ))
4164
+ ] });
4165
+ }
4166
+
4167
+ // src/LinkPreview.tsx
4168
+ import { useSyncExternalStore } from "react";
4169
+
4170
+ // src/LinkRow.tsx
4171
+ import { Fragment as Fragment15, jsx as jsx60, jsxs as jsxs41 } from "react/jsx-runtime";
4172
+ function LinkUnavailable({ kind, noun, openIn }) {
4173
+ return /* @__PURE__ */ jsxs41(Card, { fill: "none", unreadable: true, className: "flex h-9 items-center gap-2 px-3", children: [
4174
+ /* @__PURE__ */ jsx60(LinkedIcon, { kind }),
4175
+ /* @__PURE__ */ jsxs41("span", { className: "min-w-0 flex-1 truncate text-body-2 text-text-muted", children: [
4176
+ noun,
4177
+ " \u2014 not available."
4178
+ ] }),
4179
+ openIn && /* @__PURE__ */ jsx60("span", { className: "shrink-0 text-caption text-text-secondary", children: /* @__PURE__ */ jsxs41(Link, { href: openIn.href, variant: "quiet", external: true, children: [
4180
+ "Open in ",
4181
+ openIn.app,
4182
+ " \u2197"
4183
+ ] }) })
4184
+ ] });
4185
+ }
4186
+ function LinkRow({ link, preview = true }) {
4187
+ if (link.state === "loading") {
4188
+ return /* @__PURE__ */ jsx60("div", { className: "animate-skeleton-in", "aria-busy": true, children: /* @__PURE__ */ jsxs41(Card, { fill: "inset", "aria-hidden": true, className: "flex h-9 items-center gap-2 px-3", children: [
4189
+ /* @__PURE__ */ jsx60(LinkedIcon, { kind: link.kind }),
4190
+ /* @__PURE__ */ jsx60(SkeletonBar, { on: "inset", className: "h-3 w-2/5" }),
4191
+ /* @__PURE__ */ jsx60(SkeletonBar, { on: "inset", shape: "round", className: "ml-auto size-4" })
4192
+ ] }) });
4193
+ }
4194
+ if (link.state === "unavailable") return /* @__PURE__ */ jsx60(LinkUnavailable, { kind: link.kind, noun: link.noun, openIn: link.openIn });
4195
+ const { linked } = link;
4196
+ const status = chosenOf(linked.status);
4197
+ const owner = chosenOf(linked.owner);
4198
+ const said = linked.kind === "message" && linked.author;
4199
+ const row = /* @__PURE__ */ jsxs41(Card, { fill: "inset", hover: "hairline", className: "relative flex h-9 items-center gap-2 px-3", children: [
4200
+ said ? /* @__PURE__ */ jsx60(Avatar, { name: said.name, src: said.picture, size: 16 }) : /* @__PURE__ */ jsx60(LinkedIcon, { kind: linked.kind }),
4201
+ said ? /* @__PURE__ */ jsxs41("span", { className: "flex min-w-0 flex-1 items-baseline gap-2 text-body-2", children: [
4202
+ /* @__PURE__ */ jsx60("span", { className: "shrink-0 text-body-2-strong text-text-primary", children: said.name }),
4203
+ /* @__PURE__ */ jsx60("span", { className: "contents text-text-secondary", children: /* @__PURE__ */ jsx60(Link, { href: linked.href, variant: "quiet", cover: true, truncate: true, children: linked.body ?? linked.title }) })
4204
+ ] }) : /* @__PURE__ */ jsxs41(Fragment15, { children: [
4205
+ linked.key && /* @__PURE__ */ jsx60(LinkKey, { children: linked.key }),
4206
+ /* @__PURE__ */ jsx60("span", { className: "contents text-body-2-strong text-text-primary", children: /* @__PURE__ */ jsx60(Link, { href: linked.href, variant: "quiet", cover: true, truncate: true, className: "min-w-0 flex-1", children: linked.title }) })
4207
+ ] }),
4208
+ linked.updated && /* @__PURE__ */ jsx60("span", { className: "shrink-0 text-caption text-text-secondary", children: linked.updated }),
4209
+ linked.conversation && (linked.conversation.unread || linked.kind === "topic") && /* @__PURE__ */ jsx60(CommentCount, { conversation: linked.conversation, noun: linked.conversation.noun }),
4210
+ status?.colour && !linked.done && /* @__PURE__ */ jsx60(StatusMark, { status: { label: status.label, colour: status.colour } }),
4211
+ linked.done && /* @__PURE__ */ jsx60(ProgressRing, { done: linked.done.done, total: linked.done.total }),
4212
+ owner && /* @__PURE__ */ jsx60(Avatar, { name: owner.label, src: owner.picture, size: 16 }),
4213
+ linked.members && /* @__PURE__ */ jsx60(AvatarGroup, { members: linked.members, size: 16 }),
4214
+ linked.authors && /* @__PURE__ */ jsx60(AvatarGroup, { members: linked.authors, size: 16 })
4215
+ ] });
4216
+ return preview ? /* @__PURE__ */ jsx60(LinkPreview, { linked, block: true, children: row }) : row;
4217
+ }
4218
+
4219
+ // src/LinkCard.tsx
4220
+ import { Fragment as Fragment16, jsx as jsx61, jsxs as jsxs42 } from "react/jsx-runtime";
4221
+ function LinkCard({ link, readOnly = false, bare = false }) {
4222
+ if (link.state === "loading") return /* @__PURE__ */ jsx61(LinkCardLoading, { kind: link.kind, shape: link.shape });
4223
+ if (link.state === "unavailable") return /* @__PURE__ */ jsx61(LinkUnavailable, { kind: link.kind, noun: link.noun, openIn: link.openIn });
4224
+ const { linked } = link;
4225
+ const body = linked.kind === "message" && linked.author ? /* @__PURE__ */ jsx61(SaidBody, { linked }) : /* @__PURE__ */ jsx61(CardBody, { linked, readOnly });
4226
+ if (bare) return /* @__PURE__ */ jsx61("div", { className: "flex flex-col gap-2 p-3", children: body });
4227
+ return /* @__PURE__ */ jsx61(Card, { fill: "inset", className: "flex flex-col gap-2 p-3", children: body });
4228
+ }
4229
+ function CardBody({ linked, readOnly }) {
4230
+ return /* @__PURE__ */ jsxs42(Fragment16, { children: [
4231
+ /* @__PURE__ */ jsxs42("div", { className: "flex min-h-[19.6px] items-center gap-2", children: [
4232
+ /* @__PURE__ */ jsx61("span", { className: "flex min-w-0 flex-1 text-body-2-strong text-text-primary", children: /* @__PURE__ */ jsxs42(Link, { href: linked.href, variant: "quiet", className: "flex min-w-0 flex-1 items-center gap-2", children: [
4233
+ /* @__PURE__ */ jsx61(LinkedIcon, { kind: linked.kind }),
4234
+ /* @__PURE__ */ jsx61("span", { className: "truncate", children: linked.title })
4235
+ ] }) }),
4236
+ linked.done && /* @__PURE__ */ jsx61(ProgressRing, { done: linked.done.done, total: linked.done.total }),
4237
+ linked.members && /* @__PURE__ */ jsx61(AvatarGroup, { members: linked.members, size: 16 })
4238
+ ] }),
4239
+ (linked.key || linked.subtitle) && /* @__PURE__ */ jsx61("p", { className: "-mt-1 pl-6 text-caption text-text-secondary", children: [linked.key, linked.subtitle].filter(Boolean).join(" \xB7 ") }),
4240
+ linked.summary && /* @__PURE__ */ jsx61("p", { className: "line-clamp-2 text-body-2 text-text-secondary", children: linked.summary }),
4241
+ linked.children && linked.children.length > 0 && /* @__PURE__ */ jsx61("div", { className: "flex flex-col divide-y divide-border-subtle rounded-md border border-border-subtle leaf:divide-border-strong leaf:border-border-strong", children: linked.children.map((child) => /* @__PURE__ */ jsxs42("div", { className: "relative flex h-8 items-center gap-2 px-2 hover:bg-bg-active", children: [
4242
+ /* @__PURE__ */ jsx61(StatusMark, { status: child.status }),
4243
+ child.key && /* @__PURE__ */ jsx61(LinkKey, { children: child.key }),
4244
+ /* @__PURE__ */ jsx61("span", { className: "contents text-body-2 text-text-primary", children: /* @__PURE__ */ jsx61(Link, { href: child.href, variant: "quiet", cover: true, truncate: true, className: "min-w-0 flex-1", children: child.title }) }),
4245
+ child.owner ? /* @__PURE__ */ jsx61(Avatar, { name: child.owner.name, src: child.owner.picture, size: 16 }) : /* @__PURE__ */ jsx61("span", { className: "size-4 shrink-0", "aria-hidden": true })
4246
+ ] }, child.id)) }),
4247
+ linked.latest && /* @__PURE__ */ jsxs42("div", { className: "flex flex-col gap-1", children: [
4248
+ /* @__PURE__ */ jsx61("span", { className: "text-caption text-text-muted", children: "Latest conversation" }),
4249
+ /* @__PURE__ */ jsxs42("div", { className: "flex gap-2 rounded-md border border-border-subtle p-2 leaf:border-border-strong", children: [
4250
+ /* @__PURE__ */ jsx61(Avatar, { name: linked.latest.author.name, src: linked.latest.author.picture, size: 16 }),
4251
+ /* @__PURE__ */ jsxs42("div", { className: "min-w-0 flex-1", children: [
4252
+ /* @__PURE__ */ jsxs42("div", { className: "flex items-baseline gap-2 text-caption", children: [
4253
+ /* @__PURE__ */ jsx61("span", { className: "text-text-primary", children: linked.latest.author.name }),
4254
+ /* @__PURE__ */ jsx61("span", { className: "text-text-muted", children: linked.latest.at })
4255
+ ] }),
4256
+ /* @__PURE__ */ jsx61("p", { className: "line-clamp-2 text-body-2 text-text-secondary", children: linked.latest.body })
4257
+ ] })
4258
+ ] })
4259
+ ] }),
4260
+ /* @__PURE__ */ jsxs42("div", { className: "flex min-h-6 items-center gap-2 border-t border-border-subtle pt-2 leaf:border-border-strong", children: [
4261
+ (linked.status || linked.owner) && /* @__PURE__ */ jsx61(LinkPickers, { status: linked.status, owner: linked.owner, ownerLabel: linked.ownerLabel, readOnly }),
4262
+ linked.authors ? /* @__PURE__ */ jsxs42("span", { className: "flex min-w-0 items-center gap-2 text-caption text-text-secondary", children: [
4263
+ /* @__PURE__ */ jsx61(AvatarGroup, { members: linked.authors, size: 16 }),
4264
+ linked.updated && /* @__PURE__ */ jsx61("span", { className: "shrink-0", children: linked.updated })
4265
+ ] }) : !linked.status && !linked.owner && linked.updated && /* @__PURE__ */ jsxs42("span", { className: "text-caption text-text-secondary", children: [
4266
+ "Updated ",
4267
+ linked.updated
4268
+ ] }),
4269
+ linked.conversation && /* @__PURE__ */ jsx61("span", { className: "ml-auto flex", children: /* @__PURE__ */ jsx61(CommentCount, { conversation: linked.conversation, noun: linked.conversation.noun }) })
4270
+ ] })
4271
+ ] });
4272
+ }
4273
+ function SaidBody({ linked }) {
4274
+ const author = linked.author;
4275
+ return /* @__PURE__ */ jsxs42(Fragment16, { children: [
4276
+ /* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-2", children: [
4277
+ /* @__PURE__ */ jsx61(Avatar, { name: author.name, src: author.picture, size: 24 }),
4278
+ /* @__PURE__ */ jsx61("span", { className: "text-body-2-strong text-text-primary", children: author.name }),
4279
+ /* @__PURE__ */ jsx61("span", { className: "text-caption text-text-muted", children: /* @__PURE__ */ jsx61(Link, { href: linked.href, variant: "quiet", children: linked.updated ?? "Open" }) })
4280
+ ] }),
4281
+ /* @__PURE__ */ jsx61("p", { className: "line-clamp-4 text-body-2 text-text-primary", children: linked.body ?? linked.title })
4282
+ ] });
4283
+ }
4284
+ var KIND_SHAPE = {
4285
+ issue: { subtitle: true, summary: true, footer: "pickers" },
4286
+ project: { subtitle: false, summary: true, rows: 3, ring: true, footer: "pickers" },
4287
+ topic: { summary: true, latest: true, footer: "line" },
4288
+ page: { subtitle: true, summary: true, footer: "people" },
4289
+ file: { summary: false, footer: "line" },
4290
+ message: { summary: true, footer: "none" }
4291
+ };
4292
+ function LinkCardLoading({ kind, shape }) {
4293
+ const { subtitle = false, summary = true, rows = 0, latest = false, ring = false, footer = "line" } = shape ?? KIND_SHAPE[kind];
4294
+ return /* @__PURE__ */ jsx61("div", { className: "animate-skeleton-in", "aria-busy": true, children: /* @__PURE__ */ jsxs42(Card, { fill: "inset", "aria-hidden": true, className: "flex flex-col gap-2 p-3", children: [
4295
+ /* @__PURE__ */ jsxs42("div", { className: "flex h-[19.6px] items-center gap-2", children: [
4296
+ /* @__PURE__ */ jsx61(LinkedIcon, { kind }),
4297
+ /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-3.5 w-1/2" }),
4298
+ ring && /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", shape: "round", className: "ml-auto size-4" })
4299
+ ] }),
4300
+ subtitle && /* @__PURE__ */ jsx61("div", { className: "-mt-1 flex h-[14.4px] items-center pl-6", children: /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-2.5 w-20" }) }),
4301
+ summary && /* @__PURE__ */ jsx61("div", { className: "flex h-[19.6px] items-center", children: /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-3 w-4/5" }) }),
4302
+ rows > 0 && /* @__PURE__ */ jsx61("div", { className: "flex flex-col divide-y divide-border-subtle rounded-md border border-border-subtle leaf:divide-border-strong leaf:border-border-strong", children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx61("div", { className: "flex h-8 items-center px-2", children: /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-3 w-1/3" }) }, i)) }),
4303
+ latest && /* @__PURE__ */ jsxs42("div", { className: "flex flex-col gap-1", children: [
4304
+ /* @__PURE__ */ jsx61("div", { className: "flex h-[14.4px] items-center", children: /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-2.5 w-28" }) }),
4305
+ /* @__PURE__ */ jsxs42("div", { className: "flex h-[71.6px] flex-col justify-center gap-2 rounded-md border border-border-subtle p-2 leaf:border-border-strong", children: [
4306
+ /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-2.5 w-24" }),
4307
+ /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-3 w-full" }),
4308
+ /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-3 w-3/5" })
4309
+ ] })
4310
+ ] }),
4311
+ footer !== "none" && /* @__PURE__ */ jsx61("div", { className: "flex min-h-6 items-center gap-2 border-t border-border-subtle pt-2 leaf:border-border-strong", children: footer === "pickers" ? /* @__PURE__ */ jsxs42(Fragment16, { children: [
4312
+ /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", shape: "control", className: "h-6 w-24" }),
4313
+ /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", shape: "control", className: "h-6 w-28" })
4314
+ ] }) : footer === "people" ? /* @__PURE__ */ jsxs42(Fragment16, { children: [
4315
+ /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", shape: "round", className: "size-4" }),
4316
+ /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-3 w-40" })
4317
+ ] }) : /* @__PURE__ */ jsx61(SkeletonBar, { on: "inset", className: "h-3 w-40" }) })
4318
+ ] }) });
4319
+ }
4320
+
4321
+ // src/LinkPreview.tsx
4322
+ import { Fragment as Fragment17, jsx as jsx62 } from "react/jsx-runtime";
4323
+ var HOVER = "(hover: hover)";
4324
+ function subscribe(onChange) {
4325
+ if (typeof window === "undefined" || !window.matchMedia) return () => {
4326
+ };
4327
+ const query = window.matchMedia(HOVER);
4328
+ query.addEventListener("change", onChange);
4329
+ return () => query.removeEventListener("change", onChange);
4330
+ }
4331
+ function useCanHover() {
4332
+ return useSyncExternalStore(
4333
+ subscribe,
4334
+ () => typeof window === "undefined" || !window.matchMedia ? true : window.matchMedia(HOVER).matches,
4335
+ () => true
4336
+ );
4337
+ }
4338
+ function LinkPreview({ linked, block = false, children }) {
4339
+ const canHover = useCanHover();
4340
+ if (!canHover) return /* @__PURE__ */ jsx62(Fragment17, { children });
4341
+ return /* @__PURE__ */ jsx62(PreviewCard, { side: "bottom", content: /* @__PURE__ */ jsx62(LinkCard, { link: { state: "ready", linked }, bare: true, readOnly: true }), wrapperClassName: block ? "grid w-full min-w-0 grid-cols-[minmax(0,1fr)]" : "max-w-full", children });
4342
+ }
4343
+ function LinkPreviewOpen({ linked }) {
4344
+ return /* @__PURE__ */ jsx62(MenuPanel, { className: "w-[360px] p-0", children: /* @__PURE__ */ jsx62(LinkCard, { link: { state: "ready", linked }, bare: true, readOnly: true }) });
4345
+ }
4346
+
4347
+ // src/LinkChip.tsx
4348
+ import { jsx as jsx63, jsxs as jsxs43 } from "react/jsx-runtime";
4349
+ function LinkChip({ link, preview = true }) {
4350
+ if (link.state === "loading") {
4351
+ return /* @__PURE__ */ jsx63(InlineChip, { icon: /* @__PURE__ */ jsx63(LinkedIcon, { kind: link.kind, size: 14, tone: "inherit" }), "aria-busy": true, children: /* @__PURE__ */ jsx63(SkeletonBar, { className: "h-2.5 w-16" }) });
4352
+ }
4353
+ if (link.state === "unavailable") {
4354
+ return /* @__PURE__ */ jsxs43(InlineChip, { tone: "muted", icon: /* @__PURE__ */ jsx63(LinkedIcon, { kind: link.kind, size: 14, tone: "inherit" }), children: [
4355
+ link.noun,
4356
+ ", not available"
4357
+ ] });
4358
+ }
4359
+ const { linked } = link;
4360
+ const status = chosenOf(linked.status);
4361
+ const said = linked.kind === "message" && linked.author;
4362
+ const chip = /* @__PURE__ */ jsxs43(
4363
+ InlineChip,
4364
+ {
4365
+ icon: said ? /* @__PURE__ */ jsx63(Avatar, { name: said.name, src: said.picture, size: 16 }) : /* @__PURE__ */ jsx63(LinkedIcon, { kind: linked.kind, size: 14, tone: "inherit" }),
4366
+ href: linked.href,
4367
+ className: "max-w-[28ch]",
4368
+ children: [
4369
+ linked.key && /* @__PURE__ */ jsx63(LinkKey, { children: linked.key }),
4370
+ /* @__PURE__ */ jsx63("span", { className: "truncate", children: said ? `${said.name}: ${linked.body ?? linked.title}` : linked.title }),
4371
+ status?.colour && /* @__PURE__ */ jsx63(StatusMark, { status: { label: status.label, colour: status.colour } })
4372
+ ]
4373
+ }
4374
+ );
4375
+ return preview ? /* @__PURE__ */ jsx63(LinkPreview, { linked, children: chip }) : chip;
4376
+ }
4377
+
4378
+ // src/CardUnder.tsx
4379
+ import { IconX as IconX6 } from "@tabler/icons-react";
4380
+ import { jsx as jsx64, jsxs as jsxs44 } from "react/jsx-runtime";
4381
+ function CardUnder({ link, onRemove, revealOnHover = false }) {
4382
+ return /* @__PURE__ */ jsxs44("div", { className: "group/card flex max-w-[480px] items-start gap-1", children: [
4383
+ /* @__PURE__ */ jsx64("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx64(LinkCard, { link }) }),
4384
+ onRemove && // At the card's top corner: halfway down a tall card a ✕ reads as belonging to nothing.
4385
+ /* @__PURE__ */ jsx64(
4386
+ "div",
4387
+ {
4388
+ className: cn(
4389
+ "flex shrink-0 self-start pt-2",
4390
+ revealOnHover && "opacity-0 transition-opacity group-hover/card:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100"
4391
+ ),
4392
+ children: /* @__PURE__ */ jsx64(IconButton, { "aria-label": "Remove card", tooltip: "Remove card", onClick: onRemove, children: /* @__PURE__ */ jsx64(IconX6, { size: 16 }) })
4393
+ }
4394
+ )
4395
+ ] });
4396
+ }
4397
+
4398
+ // src/PartCard.tsx
4399
+ import { Fragment as Fragment18, jsx as jsx65, jsxs as jsxs45 } from "react/jsx-runtime";
4400
+ function PartCard({ state = "ready", kind, heading, href, partKey, noun = "Item", openIn, children }) {
4401
+ if (state === "loading") return /* @__PURE__ */ jsx65(LinkCardLoading, { kind, shape: { summary: true, rows: 0, footer: "none" } });
4402
+ if (state === "unavailable") return /* @__PURE__ */ jsx65(LinkUnavailable, { kind, noun: `A part of this ${noun.toLowerCase()}`, openIn });
4403
+ const header = /* @__PURE__ */ jsxs45(Fragment18, { children: [
4404
+ /* @__PURE__ */ jsx65(LinkedIcon, { kind }),
4405
+ partKey && /* @__PURE__ */ jsx65(LinkKey, { children: partKey }),
4406
+ /* @__PURE__ */ jsx65("span", { className: "truncate", children: heading })
4407
+ ] });
4408
+ return /* @__PURE__ */ jsxs45(Card, { fill: "inset", className: "flex flex-col gap-2 p-3", children: [
4409
+ /* @__PURE__ */ jsx65("span", { className: "flex min-w-0 items-center gap-2 text-body-2-strong text-text-primary", children: href ? /* @__PURE__ */ jsx65(Link, { href, variant: "quiet", className: "flex min-w-0 items-center gap-2", children: header }) : header }),
4410
+ /* @__PURE__ */ jsx65("div", { className: "border-l-2 border-border-default pl-3", children })
4411
+ ] });
4412
+ }
4413
+
4024
4414
  // src/Rail.tsx
4025
- import { jsx as jsx59 } from "react/jsx-runtime";
4415
+ import { jsx as jsx66 } from "react/jsx-runtime";
4026
4416
  function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
4027
- return /* @__PURE__ */ jsx59("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
4417
+ return /* @__PURE__ */ jsx66("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
4028
4418
  }
4029
4419
 
4030
4420
  // src/RailItem.tsx
4031
- import { jsx as jsx60, jsxs as jsxs40 } from "react/jsx-runtime";
4421
+ import { jsx as jsx67, jsxs as jsxs46 } from "react/jsx-runtime";
4032
4422
  function RailItem({ href, icon, label, active = false, className, onClick, ...props }) {
4033
4423
  const inApp = useInAppClick(href, onClick);
4034
- return /* @__PURE__ */ jsxs40(
4424
+ return /* @__PURE__ */ jsxs46(
4035
4425
  "a",
4036
4426
  {
4037
4427
  href,
@@ -4040,14 +4430,14 @@ function RailItem({ href, icon, label, active = false, className, onClick, ...pr
4040
4430
  ...props,
4041
4431
  onClick: inApp,
4042
4432
  children: [
4043
- /* @__PURE__ */ jsx60(
4433
+ /* @__PURE__ */ jsx67(
4044
4434
  "div",
4045
4435
  {
4046
4436
  className: cn(
4047
4437
  "flex items-center justify-center rounded-lg p-2 transition-colors",
4048
4438
  active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
4049
4439
  ),
4050
- children: /* @__PURE__ */ jsx60(
4440
+ children: /* @__PURE__ */ jsx67(
4051
4441
  "span",
4052
4442
  {
4053
4443
  className: cn(
@@ -4059,14 +4449,14 @@ function RailItem({ href, icon, label, active = false, className, onClick, ...pr
4059
4449
  )
4060
4450
  }
4061
4451
  ),
4062
- /* @__PURE__ */ jsx60("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
4452
+ /* @__PURE__ */ jsx67("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
4063
4453
  ]
4064
4454
  }
4065
4455
  );
4066
4456
  }
4067
4457
 
4068
4458
  // src/Property.tsx
4069
- import { jsx as jsx61, jsxs as jsxs41 } from "react/jsx-runtime";
4459
+ import { jsx as jsx68, jsxs as jsxs47 } from "react/jsx-runtime";
4070
4460
  var VALUE_CLASSES = "contents";
4071
4461
  function Property({ label, layout = "row", children, className }) {
4072
4462
  if (layout === "stacked") {
@@ -4074,25 +4464,25 @@ function Property({ label, layout = "row", children, className }) {
4074
4464
  // gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
4075
4465
  // Peek's topic-details sections already sit at 12px, Ship's rail was
4076
4466
  // 6px, and unifying means the bigger, calmer one.
4077
- /* @__PURE__ */ jsxs41("dl", { className: cn("flex flex-col gap-3", className), children: [
4078
- /* @__PURE__ */ jsx61("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
4079
- /* @__PURE__ */ jsx61("dd", { className: VALUE_CLASSES, children })
4467
+ /* @__PURE__ */ jsxs47("dl", { className: cn("flex flex-col gap-3", className), children: [
4468
+ /* @__PURE__ */ jsx68("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
4469
+ /* @__PURE__ */ jsx68("dd", { className: VALUE_CLASSES, children })
4080
4470
  ] })
4081
4471
  );
4082
4472
  }
4083
- return /* @__PURE__ */ jsxs41("dl", { className: cn("flex items-center gap-2", className), children: [
4084
- /* @__PURE__ */ jsx61("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
4085
- /* @__PURE__ */ jsx61("dd", { className: VALUE_CLASSES, children })
4473
+ return /* @__PURE__ */ jsxs47("dl", { className: cn("flex items-center gap-2", className), children: [
4474
+ /* @__PURE__ */ jsx68("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
4475
+ /* @__PURE__ */ jsx68("dd", { className: VALUE_CLASSES, children })
4086
4476
  ] });
4087
4477
  }
4088
4478
 
4089
4479
  // src/Reaction.tsx
4090
4480
  import { Toggle as Toggle2 } from "@base-ui/react/toggle";
4091
- import { jsx as jsx62, jsxs as jsxs42 } from "react/jsx-runtime";
4481
+ import { jsx as jsx69, jsxs as jsxs48 } from "react/jsx-runtime";
4092
4482
  function Reaction({ emoji, count, pressed = false, className, ...props }) {
4093
4483
  return (
4094
4484
  // @estiva-escape(no-copied-look): W1 (Katerina, 24 September: leave alone): a reaction pill shares four words with a field's box by coincidence
4095
- /* @__PURE__ */ jsxs42(
4485
+ /* @__PURE__ */ jsxs48(
4096
4486
  Toggle2,
4097
4487
  {
4098
4488
  pressed,
@@ -4114,8 +4504,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
4114
4504
  ),
4115
4505
  ...props,
4116
4506
  children: [
4117
- /* @__PURE__ */ jsx62("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
4118
- /* @__PURE__ */ jsx62("span", { className: CHIP_TEXT_CLASSES, children: count })
4507
+ /* @__PURE__ */ jsx69("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
4508
+ /* @__PURE__ */ jsx69("span", { className: CHIP_TEXT_CLASSES, children: count })
4119
4509
  ]
4120
4510
  }
4121
4511
  )
@@ -4125,9 +4515,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
4125
4515
  // src/SearchInput.tsx
4126
4516
  import "react";
4127
4517
  import { Input as Input3 } from "@base-ui/react/input";
4128
- import { jsx as jsx63, jsxs as jsxs43 } from "react/jsx-runtime";
4518
+ import { jsx as jsx70, jsxs as jsxs49 } from "react/jsx-runtime";
4129
4519
  function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
4130
- return /* @__PURE__ */ jsxs43(
4520
+ return /* @__PURE__ */ jsxs49(
4131
4521
  "div",
4132
4522
  {
4133
4523
  className: cn(
@@ -4139,7 +4529,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
4139
4529
  className
4140
4530
  ),
4141
4531
  children: [
4142
- /* @__PURE__ */ jsx63(
4532
+ /* @__PURE__ */ jsx70(
4143
4533
  Input3,
4144
4534
  {
4145
4535
  className: cn("flex-1 min-w-0 text-input-value", BARE_INPUT_CLASSES),
@@ -4147,42 +4537,42 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
4147
4537
  ...props
4148
4538
  }
4149
4539
  ),
4150
- shortcut && /* @__PURE__ */ jsx63(Kbd, { children: shortcut })
4540
+ shortcut && /* @__PURE__ */ jsx70(Kbd, { children: shortcut })
4151
4541
  ]
4152
4542
  }
4153
4543
  );
4154
4544
  }
4155
4545
 
4156
4546
  // src/Panel.tsx
4157
- import { jsx as jsx64, jsxs as jsxs44 } from "react/jsx-runtime";
4547
+ import { jsx as jsx71, jsxs as jsxs50 } from "react/jsx-runtime";
4158
4548
  function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
4159
- return /* @__PURE__ */ jsxs44("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
4160
- /* @__PURE__ */ jsx64(ContainerHeader, { title, chevron, actions }),
4549
+ return /* @__PURE__ */ jsxs50("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
4550
+ /* @__PURE__ */ jsx71(ContainerHeader, { title, chevron, actions }),
4161
4551
  broken ? (
4162
4552
  // The message takes the room the body had and centres itself in it.
4163
- /* @__PURE__ */ jsx64("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
4164
- ) : /* @__PURE__ */ jsx64(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
4165
- !broken && footer && /* @__PURE__ */ jsx64("div", { className: "shrink-0", children: footer })
4553
+ /* @__PURE__ */ jsx71("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
4554
+ ) : /* @__PURE__ */ jsx71(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
4555
+ !broken && footer && /* @__PURE__ */ jsx71("div", { className: "shrink-0", children: footer })
4166
4556
  ] });
4167
4557
  }
4168
4558
  function Panel(props) {
4169
- return /* @__PURE__ */ jsx64(
4559
+ return /* @__PURE__ */ jsx71(
4170
4560
  ErrorBoundary,
4171
4561
  {
4172
4562
  label: "panel",
4173
4563
  frame: (message) => (
4174
4564
  // Only the name comes back with the message: the actions and the footer may be what threw.
4175
- /* @__PURE__ */ jsx64(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
4565
+ /* @__PURE__ */ jsx71(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
4176
4566
  ),
4177
- children: /* @__PURE__ */ jsx64(Frame, { ...props })
4567
+ children: /* @__PURE__ */ jsx71(Frame, { ...props })
4178
4568
  }
4179
4569
  );
4180
4570
  }
4181
4571
 
4182
4572
  // src/ListColumn.tsx
4183
- import { jsx as jsx65, jsxs as jsxs45 } from "react/jsx-runtime";
4573
+ import { jsx as jsx72, jsxs as jsxs51 } from "react/jsx-runtime";
4184
4574
  function Column({ title, chevron = false, titleMenu, actions, above, collapsed = false, children, className, broken = false }) {
4185
- return /* @__PURE__ */ jsxs45(
4575
+ return /* @__PURE__ */ jsxs51(
4186
4576
  "div",
4187
4577
  {
4188
4578
  className: cn(
@@ -4193,35 +4583,35 @@ function Column({ title, chevron = false, titleMenu, actions, above, collapsed =
4193
4583
  ),
4194
4584
  "data-collapsed": collapsed || void 0,
4195
4585
  children: [
4196
- /* @__PURE__ */ jsx65(ContainerHeader, { title, chevron, titleMenu, actions }),
4586
+ /* @__PURE__ */ jsx72(ContainerHeader, { title, chevron, titleMenu, actions }),
4197
4587
  above,
4198
4588
  broken ? (
4199
4589
  // The message takes the room the list had and centres itself in it (Katerina, 19 September).
4200
- /* @__PURE__ */ jsx65("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
4201
- ) : /* @__PURE__ */ jsx65(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
4590
+ /* @__PURE__ */ jsx72("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
4591
+ ) : /* @__PURE__ */ jsx72(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
4202
4592
  ]
4203
4593
  }
4204
4594
  );
4205
4595
  }
4206
4596
  function ListColumn(props) {
4207
- return /* @__PURE__ */ jsx65(
4597
+ return /* @__PURE__ */ jsx72(
4208
4598
  ErrorBoundary,
4209
4599
  {
4210
4600
  label: "list panel",
4211
4601
  frame: (message) => (
4212
4602
  // Only the name comes back with the message: the actions and the row above may be what threw.
4213
- /* @__PURE__ */ jsx65(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
4603
+ /* @__PURE__ */ jsx72(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
4214
4604
  ),
4215
- children: /* @__PURE__ */ jsx65(Column, { ...props })
4605
+ children: /* @__PURE__ */ jsx72(Column, { ...props })
4216
4606
  }
4217
4607
  );
4218
4608
  }
4219
4609
 
4220
4610
  // src/Tabs.tsx
4221
4611
  import { Tabs as BaseTabs } from "@base-ui/react/tabs";
4222
- import { Fragment as Fragment15, jsx as jsx66, jsxs as jsxs46 } from "react/jsx-runtime";
4612
+ import { Fragment as Fragment19, jsx as jsx73, jsxs as jsxs52 } from "react/jsx-runtime";
4223
4613
  function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
4224
- return /* @__PURE__ */ jsx66(
4614
+ return /* @__PURE__ */ jsx73(
4225
4615
  BaseTabs.Root,
4226
4616
  {
4227
4617
  value: active,
@@ -4229,14 +4619,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
4229
4619
  if (details.reason === "none") onChange(value);
4230
4620
  },
4231
4621
  className,
4232
- children: /* @__PURE__ */ jsx66(
4622
+ children: /* @__PURE__ */ jsx73(
4233
4623
  BaseTabs.List,
4234
4624
  {
4235
4625
  activateOnFocus: true,
4236
4626
  "aria-label": aria["aria-label"],
4237
4627
  "aria-labelledby": aria["aria-labelledby"],
4238
4628
  className: "flex items-center gap-2",
4239
- children: tabs.map((tab) => /* @__PURE__ */ jsxs46(
4629
+ children: tabs.map((tab) => /* @__PURE__ */ jsxs52(
4240
4630
  BaseTabs.Tab,
4241
4631
  {
4242
4632
  value: tab.id,
@@ -4249,13 +4639,13 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
4249
4639
  ),
4250
4640
  children: [
4251
4641
  tab.icon,
4252
- /* @__PURE__ */ jsxs46("span", { className: "flex items-baseline", children: [
4642
+ /* @__PURE__ */ jsxs52("span", { className: "flex items-baseline", children: [
4253
4643
  tab.label,
4254
- tab.count !== void 0 ? /* @__PURE__ */ jsx66("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
4644
+ tab.count !== void 0 ? /* @__PURE__ */ jsx73("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
4255
4645
  ] }),
4256
- tab.unread ? /* @__PURE__ */ jsxs46(Fragment15, { children: [
4257
- /* @__PURE__ */ jsx66(UnreadDot, { className: "h-auto w-auto" }),
4258
- /* @__PURE__ */ jsx66("span", { className: "sr-only", children: "new" })
4646
+ tab.unread ? /* @__PURE__ */ jsxs52(Fragment19, { children: [
4647
+ /* @__PURE__ */ jsx73(UnreadDot, { className: "h-auto w-auto" }),
4648
+ /* @__PURE__ */ jsx73("span", { className: "sr-only", children: "new" })
4259
4649
  ] }) : null
4260
4650
  ]
4261
4651
  },
@@ -4270,8 +4660,8 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
4270
4660
  // src/Toast.tsx
4271
4661
  import { createContext as createContext7, useContext as useContext7, useMemo as useMemo6 } from "react";
4272
4662
  import { Toast as BaseToast } from "@base-ui/react/toast";
4273
- import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
4274
- import { jsx as jsx67, jsxs as jsxs47 } from "react/jsx-runtime";
4663
+ import { IconAlertCircle as IconAlertCircle2, IconCircleCheck as IconCircleCheck2, IconCircleX as IconCircleX2 } from "@tabler/icons-react";
4664
+ import { jsx as jsx74, jsxs as jsxs53 } from "react/jsx-runtime";
4275
4665
  var SURFACE_STYLES = {
4276
4666
  success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
4277
4667
  brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
@@ -4280,11 +4670,11 @@ var SURFACE_STYLES = {
4280
4670
  error: "bg-error-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md"
4281
4671
  };
4282
4672
  var ICONS2 = {
4283
- success: IconCircleCheck,
4284
- brand: IconCircleCheck,
4285
- neutral: IconCircleCheck,
4673
+ success: IconCircleCheck2,
4674
+ brand: IconCircleCheck2,
4675
+ neutral: IconCircleCheck2,
4286
4676
  warning: IconAlertCircle2,
4287
- error: IconCircleX
4677
+ error: IconCircleX2
4288
4678
  };
4289
4679
  var ICON_STYLES = {
4290
4680
  success: "signal:text-success-default signal:drop-shadow-glow-success",
@@ -4307,16 +4697,16 @@ var pillClassName = (type, hasAction, className) => cn(
4307
4697
  );
4308
4698
  function LeadingIcon({ type }) {
4309
4699
  const Icon = ICONS2[type];
4310
- return /* @__PURE__ */ jsx67(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
4700
+ return /* @__PURE__ */ jsx74(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
4311
4701
  }
4312
4702
  function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
4313
4703
  const hasAction = !!(actionLabel && onAction);
4314
- return /* @__PURE__ */ jsxs47("div", { className: pillClassName(type, hasAction, className), children: [
4315
- /* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2 shrink-0", children: [
4316
- leadingIcon && /* @__PURE__ */ jsx67(LeadingIcon, { type }),
4317
- /* @__PURE__ */ jsx67("span", { className: LABEL_CLASSES, children: label })
4704
+ return /* @__PURE__ */ jsxs53("div", { className: pillClassName(type, hasAction, className), children: [
4705
+ /* @__PURE__ */ jsxs53("div", { className: "flex items-center gap-2 shrink-0", children: [
4706
+ leadingIcon && /* @__PURE__ */ jsx74(LeadingIcon, { type }),
4707
+ /* @__PURE__ */ jsx74("span", { className: LABEL_CLASSES, children: label })
4318
4708
  ] }),
4319
- hasAction && /* @__PURE__ */ jsx67(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
4709
+ hasAction && /* @__PURE__ */ jsx74(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
4320
4710
  ] });
4321
4711
  }
4322
4712
  var ToastContext = createContext7(null);
@@ -4337,9 +4727,9 @@ function ToastProvider({ children }) {
4337
4727
  }),
4338
4728
  [manager]
4339
4729
  );
4340
- return /* @__PURE__ */ jsx67(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs47(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
4730
+ return /* @__PURE__ */ jsx74(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs53(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
4341
4731
  children,
4342
- /* @__PURE__ */ jsx67(BaseToast.Portal, { children: /* @__PURE__ */ jsx67(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx67(ToastList, {}) }) })
4732
+ /* @__PURE__ */ jsx74(BaseToast.Portal, { children: /* @__PURE__ */ jsx74(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx74(ToastList, {}) }) })
4343
4733
  ] }) });
4344
4734
  }
4345
4735
  function ToastList() {
@@ -4347,25 +4737,25 @@ function ToastList() {
4347
4737
  return toasts.map((toast) => {
4348
4738
  const type = toast.type ?? "neutral";
4349
4739
  const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
4350
- return /* @__PURE__ */ jsxs47(
4740
+ return /* @__PURE__ */ jsxs53(
4351
4741
  BaseToast.Root,
4352
4742
  {
4353
4743
  toast,
4354
4744
  swipeDirection: ["left", "down"],
4355
4745
  className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
4356
4746
  children: [
4357
- /* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2 shrink-0", children: [
4358
- leadingIcon && /* @__PURE__ */ jsx67(LeadingIcon, { type }),
4359
- /* @__PURE__ */ jsx67(BaseToast.Title, { render: /* @__PURE__ */ jsx67("span", {}), className: LABEL_CLASSES })
4747
+ /* @__PURE__ */ jsxs53("div", { className: "flex items-center gap-2 shrink-0", children: [
4748
+ leadingIcon && /* @__PURE__ */ jsx74(LeadingIcon, { type }),
4749
+ /* @__PURE__ */ jsx74(BaseToast.Title, { render: /* @__PURE__ */ jsx74("span", {}), className: LABEL_CLASSES })
4360
4750
  ] }),
4361
- actionLabel && /* @__PURE__ */ jsx67(
4751
+ actionLabel && /* @__PURE__ */ jsx74(
4362
4752
  BaseToast.Action,
4363
4753
  {
4364
4754
  onClick: () => {
4365
4755
  onAction?.();
4366
4756
  close(toast.id);
4367
4757
  },
4368
- render: /* @__PURE__ */ jsx67(Button, { variant: "outlined", size: "small", children: actionLabel })
4758
+ render: /* @__PURE__ */ jsx74(Button, { variant: "outlined", size: "small", children: actionLabel })
4369
4759
  }
4370
4760
  )
4371
4761
  ]
@@ -4390,6 +4780,7 @@ export {
4390
4780
  Breadcrumb,
4391
4781
  Button,
4392
4782
  Card,
4783
+ CardUnder,
4393
4784
  Checkbox,
4394
4785
  Chip,
4395
4786
  ChipInput,
@@ -4401,6 +4792,7 @@ export {
4401
4792
  CommandPaletteQuote,
4402
4793
  CommandPaletteSearch,
4403
4794
  CommandPaletteWorking,
4795
+ CommentCount,
4404
4796
  ConfirmDialog,
4405
4797
  ContainerHeader,
4406
4798
  DialogShell,
@@ -4424,6 +4816,16 @@ export {
4424
4816
  KindIcon,
4425
4817
  Lightbox,
4426
4818
  Link,
4819
+ LinkCard,
4820
+ LinkCardLoading,
4821
+ LinkChip,
4822
+ LinkKey,
4823
+ LinkPickers,
4824
+ LinkPreview,
4825
+ LinkPreviewOpen,
4826
+ LinkRow,
4827
+ LinkUnavailable,
4828
+ LinkedIcon,
4427
4829
  ListColumn,
4428
4830
  MembersDialog,
4429
4831
  MembersPill,
@@ -4438,11 +4840,13 @@ export {
4438
4840
  NavTree,
4439
4841
  NavTreeSection,
4440
4842
  Panel,
4843
+ PartCard,
4441
4844
  Person,
4442
4845
  PersonTrigger,
4443
4846
  Popover,
4444
4847
  PreviewCard,
4445
4848
  ProgressBar,
4849
+ ProgressRing,
4446
4850
  Property,
4447
4851
  Rail,
4448
4852
  RailItem,
@@ -4459,6 +4863,7 @@ export {
4459
4863
  SkeletonBar,
4460
4864
  SkeletonList,
4461
4865
  SkeletonRow,
4866
+ StatusMark,
4462
4867
  SuggestionMenu,
4463
4868
  Tabs,
4464
4869
  TextInput,
@@ -4477,14 +4882,18 @@ export {
4477
4882
  WithTooltip,
4478
4883
  blockAtY,
4479
4884
  calloutLook,
4885
+ chosenOf,
4480
4886
  cn,
4481
4887
  hueFor,
4482
4888
  initialsFor,
4483
4889
  inlineChipClassName,
4484
4890
  isApplePlatform,
4891
+ loadingShapeOf,
4485
4892
  richTextClassName,
4486
4893
  shortcutLabel,
4487
4894
  thingKindOf,
4895
+ unavailableMemory,
4896
+ useCanHover,
4488
4897
  useToast
4489
4898
  };
4490
4899
  //# sourceMappingURL=index.js.map