@burdenoff/microfe-brainyrich 2026.720.1 → 2026.731.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
- import { useAcknowledgeInsight as e, useCreateRebalanceProposal as t, useDismissInsight as n, usePagedInsights as r, usePortfolios as i, useRebalanceProposals as a, useResolveInsight as o, useTransitionRebalanceProposal as s } from "../hooks/useBrainyRichApi.js";
2
- import { LoadMore as c } from "../components/LoadMore.js";
3
- import { ConfirmDialog as ee } from "../components/ConfirmDialog.js";
4
- import { ActorName as l } from "../components/ActorName.js";
5
- import { DonutChart as te, FadeIn as u, GlassCard as ne, LifecycleStepper as d, StatTile as f } from "../components/viz.js";
1
+ import { useAcknowledgeInsight as e, useCreateRebalanceProposal as t, useDismissInsight as n, useGenerateRiskInsights as r, useHarvestTaxLossInsights as i, usePagedInsights as a, usePortfolioRiskSignals as o, usePortfolioRiskSummary as s, usePortfolios as ee, useRebalanceProposals as te, useResolveInsight as ne, useTaxLossOpportunities as re, useTransitionRebalanceProposal as ie } from "../hooks/useBrainyRichApi.js";
2
+ import { LoadMore as ae } from "../components/LoadMore.js";
3
+ import { ConfirmDialog as oe } from "../components/ConfirmDialog.js";
4
+ import { ActorName as c } from "../components/ActorName.js";
5
+ import { DonutChart as se, FadeIn as l, GlassCard as ce, LifecycleStepper as le, StatTile as u } from "../components/viz.js";
6
6
  import "../components/index.js";
7
- import { EmptyState as p, ErrorState as re, LoadingState as ie, SectionShell as ae, formatDate as m, formatMoney as oe, formatPct as h, statusBadgeVariant as g } from "./_shared.js";
8
- import { CommentThread as se } from "../components/reuse/CommentThread.js";
9
- import { useMemo as _, useState as v } from "react";
10
- import { Activity as ce, AlertTriangle as le, ArrowRight as ue, Check as y, Eye as de, Gauge as fe, Layers as pe, MoreHorizontal as me, Plus as he, Scale as b, ShieldAlert as x, ShieldCheck as S, TrendingUp as ge, X as C } from "lucide-react";
11
- import { Fragment as _e, jsx as w, jsxs as T } from "react/jsx-runtime";
12
- import { Badge as E, Button as D, Card as ve, CardContent as ye, CardDescription as be, CardHeader as xe, CardTitle as Se, Dialog as Ce, DialogClose as we, DialogContent as O, DialogDescription as k, DialogFooter as Te, DialogHeader as Ee, DialogTitle as De, DropdownMenu as Oe, DropdownMenuContent as ke, DropdownMenuItem as A, DropdownMenuLabel as Ae, DropdownMenuSeparator as je, DropdownMenuTrigger as Me, Input as Ne, Label as j, Select as Pe, SelectContent as Fe, SelectItem as Ie, SelectTrigger as Le, SelectValue as Re, Table as ze, TableBody as M, TableCell as N, TableHead as P, TableHeader as Be, TableRow as F, Textarea as Ve } from "@burdenoff/fe-libs/ui";
7
+ import { EmptyState as d, ErrorState as f, LoadingState as p, SectionShell as ue, formatDate as m, formatMoney as h, formatPct as g, statusBadgeVariant as _ } from "./_shared.js";
8
+ import { CommentThread as de } from "../components/reuse/CommentThread.js";
9
+ import { useMemo as v, useState as y } from "react";
10
+ import { Activity as fe, AlertTriangle as pe, ArrowRight as me, Check as he, Eye as ge, Gauge as b, Layers as _e, MoreHorizontal as ve, Plus as ye, RefreshCw as be, Scale as x, Scissors as S, ShieldAlert as C, ShieldCheck as w, Sparkles as xe, TrendingUp as Se, X as T } from "lucide-react";
11
+ import { Fragment as Ce, jsx as E, jsxs as D } from "react/jsx-runtime";
12
+ import { Badge as O, Button as k, Card as A, CardContent as j, CardDescription as M, CardHeader as N, CardTitle as P, Dialog as we, DialogClose as Te, DialogContent as Ee, DialogDescription as De, DialogFooter as Oe, DialogHeader as ke, DialogTitle as Ae, DropdownMenu as je, DropdownMenuContent as Me, DropdownMenuItem as F, DropdownMenuLabel as Ne, DropdownMenuSeparator as Pe, DropdownMenuTrigger as Fe, Input as Ie, Label as I, Select as Le, SelectContent as Re, SelectItem as ze, SelectTrigger as Be, SelectValue as Ve, Table as He, TableBody as Ue, TableCell as L, TableHead as R, TableHeader as We, TableRow as z, Textarea as Ge } from "@burdenoff/fe-libs/ui";
13
13
  //#region src/brainyrich/pages/RiskPage.tsx
14
- var He = {
14
+ var Ke = {
15
15
  DRAFT: ["PROPOSED", "CANCELLED"],
16
16
  PROPOSED: [
17
17
  "APPROVED",
@@ -22,49 +22,49 @@ var He = {
22
22
  REJECTED: [],
23
23
  EXECUTED: [],
24
24
  CANCELLED: []
25
- }, Ue = new Set([
25
+ }, qe = new Set([
26
26
  "DRIFT",
27
27
  "CONCENTRATION_RISK",
28
28
  "REBALANCE_DUE",
29
29
  "CASH_DRAG",
30
30
  "FEE_ANOMALY"
31
31
  ]);
32
- function I(e) {
32
+ function B(e) {
33
33
  return e.toLowerCase().split("_").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
34
34
  }
35
- var L = [
35
+ var V = [
36
36
  "Draft",
37
37
  "Proposed",
38
38
  "Approved",
39
39
  "Executed"
40
- ], We = {
40
+ ], Je = {
41
41
  DRAFT: "neutral",
42
42
  PROPOSED: "warning",
43
43
  APPROVED: "blue",
44
44
  EXECUTED: "success",
45
45
  REJECTED: "error",
46
46
  CANCELLED: "neutral"
47
- }, Ge = [
47
+ }, Ye = [
48
48
  "PROPOSED",
49
49
  "DRAFT",
50
50
  "APPROVED",
51
51
  "EXECUTED",
52
52
  "REJECTED",
53
53
  "CANCELLED"
54
- ], Ke = {
54
+ ], Xe = {
55
55
  CRITICAL: "error",
56
56
  HIGH: "warning",
57
57
  MEDIUM: "info",
58
58
  LOW: "teal",
59
59
  INFO: "neutral"
60
- }, qe = [
60
+ }, Ze = [
61
61
  "CRITICAL",
62
62
  "HIGH",
63
63
  "MEDIUM",
64
64
  "LOW",
65
65
  "INFO"
66
66
  ];
67
- function Je(e) {
67
+ function Qe(e) {
68
68
  if (!Array.isArray(e) || e.length === 0) return null;
69
69
  let t = [];
70
70
  for (let n of e) {
@@ -101,11 +101,14 @@ function Je(e) {
101
101
  }
102
102
  return t;
103
103
  }
104
- function Ye(e) {
104
+ function H(e) {
105
+ return e == null ? "—" : typeof e == "number" ? Number.isInteger(e) ? e.toLocaleString() : e.toLocaleString(void 0, { maximumFractionDigits: 2 }) : typeof e == "boolean" ? e ? "Yes" : "No" : typeof e == "string" ? e : JSON.stringify(e);
106
+ }
107
+ function U(e) {
105
108
  let t = (e ?? "").toUpperCase();
106
109
  return t.includes("BUY") || t.includes("ADD") ? "text-status-success-text" : t.includes("SELL") || t.includes("TRIM") || t.includes("REDUCE") ? "text-status-error-text" : "text-text-secondary";
107
110
  }
108
- function Xe(e) {
111
+ function $e(e) {
109
112
  if (e == null) return "—";
110
113
  if (Array.isArray(e)) return `${e.length} trade${e.length === 1 ? "" : "s"}`;
111
114
  if (typeof e == "object") {
@@ -114,133 +117,133 @@ function Xe(e) {
114
117
  }
115
118
  return String(e);
116
119
  }
117
- var Ze = {
120
+ var et = {
118
121
  portfolioId: "",
119
122
  driftPct: "",
120
123
  rationale: "",
121
124
  trades: ""
122
125
  };
123
- function Qe(e) {
126
+ function tt(e) {
124
127
  if (e.trim() === "") return;
125
128
  let t = Number(e);
126
129
  return Number.isFinite(t) ? t : void 0;
127
130
  }
128
- function $e() {
129
- let { data: l, isLoading: d, isError: oe, refetch: se } = a(), { data: y } = i(), { items: L, hasMore: Je, loadMore: Ye, isLoading: $e, isFetchingNextPage: nt, isError: rt, refetch: it } = r(), R = t(), z = s(), at = e(), ot = n(), st = o(), [ct, B] = v(!1), [V, H] = v(Ze), [lt, U] = v(null), [W, G] = v(null), [K, q] = v(null), J = _(() => {
131
+ function W() {
132
+ let { data: c, isLoading: le, isError: de, refetch: he } = te(), { data: V } = ee(), [Qe, H] = y(void 0), U = Qe ?? V[0]?.id ?? "", { data: W, isLoading: ot, isError: st, refetch: ct } = o(U || void 0), G = r(), { data: K, isFetching: lt, refetch: ut } = s(U || void 0), { data: q, isLoading: dt, isError: ft, refetch: pt } = re(U || void 0), mt = i(), { items: ht, hasMore: gt, loadMore: _t, isLoading: vt, isFetchingNextPage: yt, isError: bt, refetch: xt } = a(), St = t(), J = ie(), Ct = e(), wt = n(), Tt = ne(), [Et, Dt] = y(!1), [Y, X] = y(et), [Ot, kt] = y(null), [At, jt] = y(null), [Z, Mt] = y(null), Q = v(() => {
130
133
  let e = /* @__PURE__ */ new Map();
131
- for (let t of y) e.set(t.id, t);
134
+ for (let t of V) e.set(t.id, t);
132
135
  return e;
133
- }, [y]), Y = _(() => L.filter((e) => Ue.has(e.type)), [L]), ut = l.filter((e) => e.status === "DRAFT" || e.status === "PROPOSED" || e.status === "APPROVED"), X = Y.filter((e) => e.status === "OPEN"), dt = l.length > 0 ? l.reduce((e, t) => e + (t.driftPct ?? 0), 0) / l.length : null, ft = _(() => l.filter((e) => {
134
- let t = J.get(e.portfolioId)?.driftThresholdPct;
136
+ }, [V]), Nt = v(() => ht.filter((e) => qe.has(e.type)), [ht]), Pt = c.filter((e) => e.status === "DRAFT" || e.status === "PROPOSED" || e.status === "APPROVED"), $ = Nt.filter((e) => e.status === "OPEN"), Ft = c.length > 0 ? c.reduce((e, t) => e + (t.driftPct ?? 0), 0) / c.length : null, It = v(() => c.filter((e) => {
137
+ let t = Q.get(e.portfolioId)?.driftThresholdPct;
135
138
  return t != null && Number.isFinite(t) && e.driftPct >= t;
136
- }).length, [l, J]), pt = _(() => [...l].sort((e, t) => new Date(e.createdAt).getTime() - new Date(t.createdAt).getTime()).map((e) => e.driftPct).filter((e) => Number.isFinite(e)), [l]), mt = _(() => {
139
+ }).length, [c, Q]), Lt = v(() => [...c].sort((e, t) => new Date(e.createdAt).getTime() - new Date(t.createdAt).getTime()).map((e) => e.driftPct).filter((e) => Number.isFinite(e)), [c]), Rt = v(() => {
137
140
  let e = /* @__PURE__ */ new Map();
138
- for (let t of l) e.set(t.status, (e.get(t.status) ?? 0) + 1);
139
- return Ge.filter((t) => (e.get(t) ?? 0) > 0).map((t) => ({
140
- label: I(t),
141
+ for (let t of c) e.set(t.status, (e.get(t.status) ?? 0) + 1);
142
+ return Ye.filter((t) => (e.get(t) ?? 0) > 0).map((t) => ({
143
+ label: B(t),
141
144
  value: e.get(t) ?? 0,
142
- tone: We[t]
145
+ tone: Je[t]
143
146
  }));
144
- }, [l]), Z = _(() => {
147
+ }, [c]), zt = v(() => {
145
148
  let e = /* @__PURE__ */ new Map();
146
- for (let t of X) e.set(t.severity, (e.get(t.severity) ?? 0) + 1);
147
- return qe.filter((t) => (e.get(t) ?? 0) > 0).map((t) => ({
148
- label: I(t),
149
+ for (let t of $) e.set(t.severity, (e.get(t.severity) ?? 0) + 1);
150
+ return Ze.filter((t) => (e.get(t) ?? 0) > 0).map((t) => ({
151
+ label: B(t),
149
152
  value: e.get(t) ?? 0,
150
- tone: Ke[t]
153
+ tone: Xe[t]
151
154
  }));
152
- }, [X]), Q = y.length > 0;
153
- function ht() {
154
- H(Ze), U(null), B(!0);
155
+ }, [$]), Bt = V.length > 0;
156
+ function Vt() {
157
+ X(et), kt(null), Dt(!0);
155
158
  }
156
- function gt() {
157
- if (!V.portfolioId) return;
159
+ function Ht() {
160
+ if (!Y.portfolioId) return;
158
161
  let e;
159
- if (V.trades.trim() !== "") try {
160
- e = JSON.parse(V.trades);
162
+ if (Y.trades.trim() !== "") try {
163
+ e = JSON.parse(Y.trades);
161
164
  } catch {
162
- U("Trades must be valid JSON.");
165
+ kt("Trades must be valid JSON.");
163
166
  return;
164
167
  }
165
- let t = J.get(V.portfolioId);
166
- R.mutate({
167
- portfolioId: V.portfolioId,
168
+ let t = Q.get(Y.portfolioId);
169
+ St.mutate({
170
+ portfolioId: Y.portfolioId,
168
171
  householdId: t?.householdId ?? null,
169
- driftPct: Qe(V.driftPct),
170
- rationale: V.rationale.trim() || null,
172
+ driftPct: tt(Y.driftPct),
173
+ rationale: Y.rationale.trim() || null,
171
174
  ...e === void 0 ? {} : { trades: e }
172
- }, { onSuccess: () => B(!1) });
175
+ }, { onSuccess: () => Dt(!1) });
173
176
  }
174
- function $(e, t) {
177
+ function Ut(e, t) {
175
178
  if (t === "REJECTED" || t === "CANCELLED") {
176
- q({
179
+ Mt({
177
180
  proposal: e,
178
181
  status: t
179
182
  });
180
183
  return;
181
184
  }
182
- z.mutate({
185
+ J.mutate({
183
186
  id: e.id,
184
187
  status: t
185
188
  });
186
189
  }
187
- function _t(e) {
188
- let t = J.get(e.portfolioId)?.driftThresholdPct;
190
+ function Wt(e) {
191
+ let t = Q.get(e.portfolioId)?.driftThresholdPct;
189
192
  return t != null && Number.isFinite(t) && e.driftPct >= t;
190
193
  }
191
- return /* @__PURE__ */ T(ae, {
194
+ return /* @__PURE__ */ D(ue, {
192
195
  title: "Risk & Rebalancing",
193
196
  description: "Review drift-driven rebalance proposals and act on portfolio risk insights.",
194
- badges: [`${ut.length} active`, `${X.length} open insight${X.length === 1 ? "" : "s"}`],
197
+ badges: [`${Pt.length} active`, `${$.length} open insight${$.length === 1 ? "" : "s"}`],
195
198
  actionLabel: "New proposal",
196
- onAction: ht,
199
+ onAction: Vt,
197
200
  children: [
198
- /* @__PURE__ */ T("div", {
201
+ /* @__PURE__ */ D("div", {
199
202
  className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
200
203
  children: [
201
- /* @__PURE__ */ w(u, {
204
+ /* @__PURE__ */ E(l, {
202
205
  index: 0,
203
- children: /* @__PURE__ */ w(f, {
206
+ children: /* @__PURE__ */ E(u, {
204
207
  label: "Average drift",
205
- value: dt === null ? "—" : h(dt),
206
- spark: pt.length > 1 ? pt : void 0,
207
- sparkTone: ft > 0 ? "error" : "brand",
208
+ value: Ft === null ? "—" : g(Ft),
209
+ spark: Lt.length > 1 ? Lt : void 0,
210
+ sparkTone: It > 0 ? "error" : "brand",
208
211
  glow: !0,
209
- icon: /* @__PURE__ */ w(fe, {
212
+ icon: /* @__PURE__ */ E(b, {
210
213
  className: "size-4",
211
214
  "aria-hidden": "true"
212
215
  })
213
216
  })
214
217
  }),
215
- /* @__PURE__ */ w(u, {
218
+ /* @__PURE__ */ E(l, {
216
219
  index: 1,
217
- children: /* @__PURE__ */ w(f, {
220
+ children: /* @__PURE__ */ E(u, {
218
221
  label: "Active proposals",
219
- value: String(ut.length),
220
- icon: /* @__PURE__ */ w(ce, {
222
+ value: String(Pt.length),
223
+ icon: /* @__PURE__ */ E(fe, {
221
224
  className: "size-4",
222
225
  "aria-hidden": "true"
223
226
  })
224
227
  })
225
228
  }),
226
- /* @__PURE__ */ w(u, {
229
+ /* @__PURE__ */ E(l, {
227
230
  index: 2,
228
- children: /* @__PURE__ */ w(f, {
231
+ children: /* @__PURE__ */ E(u, {
229
232
  label: "Total proposals",
230
- value: String(l.length),
231
- icon: /* @__PURE__ */ w(pe, {
233
+ value: String(c.length),
234
+ icon: /* @__PURE__ */ E(_e, {
232
235
  className: "size-4",
233
236
  "aria-hidden": "true"
234
237
  })
235
238
  })
236
239
  }),
237
- /* @__PURE__ */ w(u, {
240
+ /* @__PURE__ */ E(l, {
238
241
  index: 3,
239
- children: /* @__PURE__ */ w(f, {
242
+ children: /* @__PURE__ */ E(u, {
240
243
  label: "Open risk insights",
241
- value: String(X.length),
242
- deltaTone: X.length > 0 ? "negative" : "neutral",
243
- icon: /* @__PURE__ */ w(x, {
244
+ value: String($.length),
245
+ deltaTone: $.length > 0 ? "negative" : "neutral",
246
+ icon: /* @__PURE__ */ E(C, {
244
247
  className: "size-4",
245
248
  "aria-hidden": "true"
246
249
  })
@@ -248,53 +251,53 @@ function $e() {
248
251
  })
249
252
  ]
250
253
  }),
251
- (mt.length > 0 || Z.length > 0) && !d ? /* @__PURE__ */ T("div", {
254
+ (Rt.length > 0 || zt.length > 0) && !le ? /* @__PURE__ */ D("div", {
252
255
  className: "grid gap-4 lg:grid-cols-2",
253
- children: [/* @__PURE__ */ w(u, {
256
+ children: [/* @__PURE__ */ E(l, {
254
257
  index: 0,
255
- children: /* @__PURE__ */ T(ne, {
258
+ children: /* @__PURE__ */ D(ce, {
256
259
  glow: !0,
257
260
  className: "h-full",
258
- children: [/* @__PURE__ */ T("div", {
261
+ children: [/* @__PURE__ */ D("div", {
259
262
  className: "mb-3 flex items-center gap-2",
260
- children: [/* @__PURE__ */ w(ge, {
263
+ children: [/* @__PURE__ */ E(Se, {
261
264
  className: "size-4 text-text-secondary",
262
265
  "aria-hidden": "true"
263
- }), /* @__PURE__ */ w("h2", {
266
+ }), /* @__PURE__ */ E("h2", {
264
267
  className: "text-sm font-semibold text-text-primary",
265
268
  children: "Proposal pipeline"
266
269
  })]
267
- }), /* @__PURE__ */ w(te, {
268
- data: mt,
269
- centerValue: String(l.length),
270
+ }), /* @__PURE__ */ E(se, {
271
+ data: Rt,
272
+ centerValue: String(c.length),
270
273
  centerLabel: "proposals",
271
274
  height: 200
272
275
  })]
273
276
  })
274
- }), /* @__PURE__ */ w(u, {
277
+ }), /* @__PURE__ */ E(l, {
275
278
  index: 1,
276
- children: /* @__PURE__ */ T(ne, {
279
+ children: /* @__PURE__ */ D(ce, {
277
280
  className: "h-full",
278
- children: [/* @__PURE__ */ T("div", {
281
+ children: [/* @__PURE__ */ D("div", {
279
282
  className: "mb-3 flex items-center gap-2",
280
- children: [/* @__PURE__ */ w(x, {
283
+ children: [/* @__PURE__ */ E(C, {
281
284
  className: "size-4 text-text-secondary",
282
285
  "aria-hidden": "true"
283
- }), /* @__PURE__ */ w("h2", {
286
+ }), /* @__PURE__ */ E("h2", {
284
287
  className: "text-sm font-semibold text-text-primary",
285
288
  children: "Open risk signals"
286
289
  })]
287
- }), Z.length > 0 ? /* @__PURE__ */ w(te, {
288
- data: Z,
289
- centerValue: String(X.length),
290
+ }), zt.length > 0 ? /* @__PURE__ */ E(se, {
291
+ data: zt,
292
+ centerValue: String($.length),
290
293
  centerLabel: "open",
291
294
  height: 200
292
- }) : /* @__PURE__ */ T("div", {
295
+ }) : /* @__PURE__ */ D("div", {
293
296
  className: "flex h-[200px] flex-col items-center justify-center gap-2 text-center",
294
- children: [/* @__PURE__ */ w(S, {
297
+ children: [/* @__PURE__ */ E(w, {
295
298
  className: "size-8 text-status-success-text",
296
299
  "aria-hidden": "true"
297
- }), /* @__PURE__ */ w("p", {
300
+ }), /* @__PURE__ */ E("p", {
298
301
  className: "text-sm text-text-secondary",
299
302
  children: "No open risk signals."
300
303
  })]
@@ -302,75 +305,318 @@ function $e() {
302
305
  })
303
306
  })]
304
307
  }) : null,
305
- /* @__PURE__ */ T(ve, { children: [/* @__PURE__ */ T(xe, { children: [/* @__PURE__ */ T(Se, {
308
+ /* @__PURE__ */ D(A, { children: [/* @__PURE__ */ D(N, { children: [/* @__PURE__ */ D(P, {
309
+ className: "flex items-center gap-2",
310
+ children: [/* @__PURE__ */ E(b, {
311
+ className: "h-5 w-5",
312
+ "aria-hidden": "true"
313
+ }), "Portfolio risk signals"]
314
+ }), /* @__PURE__ */ E(M, { children: "Real, explainable signals computed live from this portfolio's own holdings and target allocation — every signal below shows the real inputs and formula/threshold behind it. Informational only, never a buy/sell recommendation." })] }), /* @__PURE__ */ D(j, {
315
+ className: "space-y-4",
316
+ children: [/* @__PURE__ */ D("div", {
317
+ className: "flex flex-wrap items-center gap-3",
318
+ children: [
319
+ /* @__PURE__ */ D("div", {
320
+ className: "min-w-[220px] space-y-1.5",
321
+ children: [/* @__PURE__ */ E(I, {
322
+ htmlFor: "risk-portfolio",
323
+ children: "Portfolio"
324
+ }), /* @__PURE__ */ D(Le, {
325
+ value: U,
326
+ onValueChange: H,
327
+ children: [/* @__PURE__ */ E(Be, {
328
+ id: "risk-portfolio",
329
+ children: /* @__PURE__ */ E(Ve, { placeholder: "Select a portfolio" })
330
+ }), /* @__PURE__ */ E(Re, { children: V.map((e) => /* @__PURE__ */ E(ze, {
331
+ value: e.id,
332
+ children: e.name
333
+ }, e.id)) })]
334
+ })]
335
+ }),
336
+ /* @__PURE__ */ D(k, {
337
+ variant: "outline",
338
+ size: "sm",
339
+ className: "mt-auto",
340
+ disabled: !U || ot,
341
+ onClick: () => ct(),
342
+ children: [/* @__PURE__ */ E(be, {
343
+ className: "size-4",
344
+ "aria-hidden": "true"
345
+ }), "Recompute"]
346
+ }),
347
+ /* @__PURE__ */ D(k, {
348
+ variant: "outline",
349
+ size: "sm",
350
+ className: "mt-auto",
351
+ disabled: !U || (W?.signals.length ?? 0) === 0 || G.isPending,
352
+ onClick: () => G.mutate(U),
353
+ children: [/* @__PURE__ */ E(C, {
354
+ className: "size-4",
355
+ "aria-hidden": "true"
356
+ }), G.isPending ? "Saving…" : "Save as insights"]
357
+ })
358
+ ]
359
+ }), V.length === 0 ? /* @__PURE__ */ E(d, {
360
+ icon: /* @__PURE__ */ E(b, {
361
+ className: "size-6",
362
+ "aria-hidden": "true"
363
+ }),
364
+ title: "No portfolios yet",
365
+ description: "Create a portfolio to compute real risk signals from its holdings."
366
+ }) : ot ? /* @__PURE__ */ E(p, {}) : st ? /* @__PURE__ */ E(f, { onRetry: () => ct() }) : W ? /* @__PURE__ */ D("div", {
367
+ className: "space-y-4",
368
+ children: [
369
+ /* @__PURE__ */ D("div", {
370
+ className: "grid gap-3 sm:grid-cols-3",
371
+ children: [
372
+ /* @__PURE__ */ E(u, {
373
+ label: "Portfolio value",
374
+ value: h(W.totalValue),
375
+ icon: /* @__PURE__ */ E(_e, {
376
+ className: "size-4",
377
+ "aria-hidden": "true"
378
+ })
379
+ }),
380
+ /* @__PURE__ */ E(u, {
381
+ label: "Holdings considered",
382
+ value: String(W.holdingsConsidered),
383
+ icon: /* @__PURE__ */ E(fe, {
384
+ className: "size-4",
385
+ "aria-hidden": "true"
386
+ })
387
+ }),
388
+ /* @__PURE__ */ E(u, {
389
+ label: "Signals breached",
390
+ value: String(W.signals.length),
391
+ deltaTone: W.signals.length > 0 ? "negative" : "neutral",
392
+ icon: /* @__PURE__ */ E(C, {
393
+ className: "size-4",
394
+ "aria-hidden": "true"
395
+ })
396
+ })
397
+ ]
398
+ }),
399
+ W.signals.length === 0 ? /* @__PURE__ */ E(d, {
400
+ icon: /* @__PURE__ */ E(w, {
401
+ className: "size-6",
402
+ "aria-hidden": "true"
403
+ }),
404
+ title: "No configured threshold was breached",
405
+ description: "This portfolio's concentration, cash, drift and unrealized-loss metrics are all within their configured thresholds."
406
+ }) : /* @__PURE__ */ E("ul", {
407
+ className: "space-y-3",
408
+ children: W.signals.map((e, t) => /* @__PURE__ */ E(rt, { signal: e }, `${e.kind}-${t}`))
409
+ }),
410
+ /* @__PURE__ */ D("div", {
411
+ className: "rounded-xl border border-border-subtle bg-bg-surface p-4",
412
+ children: [/* @__PURE__ */ D("div", {
413
+ className: "flex flex-wrap items-center justify-between gap-2",
414
+ children: [/* @__PURE__ */ D("div", {
415
+ className: "flex items-center gap-2",
416
+ children: [
417
+ /* @__PURE__ */ E(xe, {
418
+ className: "size-4 text-text-secondary",
419
+ "aria-hidden": "true"
420
+ }),
421
+ /* @__PURE__ */ E("h3", {
422
+ className: "text-sm font-semibold text-text-primary",
423
+ children: "AI summary"
424
+ }),
425
+ /* @__PURE__ */ E("span", {
426
+ className: "text-xs text-text-muted",
427
+ children: "(optional — plain-language restatement of the signals above; never a source of numbers)"
428
+ })
429
+ ]
430
+ }), /* @__PURE__ */ D(k, {
431
+ variant: "outline",
432
+ size: "sm",
433
+ disabled: !U || lt,
434
+ onClick: () => ut(),
435
+ children: [/* @__PURE__ */ E(xe, {
436
+ className: "size-4",
437
+ "aria-hidden": "true"
438
+ }), lt ? "Generating…" : "Generate AI summary"]
439
+ })]
440
+ }), lt ? /* @__PURE__ */ E("p", {
441
+ className: "mt-2 text-sm text-text-secondary",
442
+ children: "Asking the AI provider…"
443
+ }) : K?.generated ? /* @__PURE__ */ D("div", {
444
+ className: "mt-2 space-y-1",
445
+ children: [/* @__PURE__ */ E("p", {
446
+ className: "text-sm text-text-primary",
447
+ children: K.summary
448
+ }), /* @__PURE__ */ D("p", {
449
+ className: "text-xs text-text-muted",
450
+ children: [
451
+ "AI-generated commentary",
452
+ K.provider ? ` · ${K.provider}` : "",
453
+ " · based on",
454
+ " ",
455
+ K.signalsConsidered,
456
+ " computed signal",
457
+ K.signalsConsidered === 1 ? "" : "s",
458
+ " above"
459
+ ]
460
+ })]
461
+ }) : K && !K.generated ? /* @__PURE__ */ D("p", {
462
+ className: "mt-2 text-sm text-text-secondary",
463
+ children: [
464
+ "AI summary unavailable — ",
465
+ K.reason ?? "no provider configured",
466
+ ". The deterministic signals above are unaffected."
467
+ ]
468
+ }) : /* @__PURE__ */ E("p", {
469
+ className: "mt-2 text-sm text-text-muted",
470
+ children: "Not generated yet. The deterministic signals above always work without this."
471
+ })]
472
+ })
473
+ ]
474
+ }) : /* @__PURE__ */ E(d, {
475
+ icon: /* @__PURE__ */ E(b, {
476
+ className: "size-6",
477
+ "aria-hidden": "true"
478
+ }),
479
+ title: "Select a portfolio",
480
+ description: "Choose a portfolio above to compute its real risk signals."
481
+ })]
482
+ })] }),
483
+ /* @__PURE__ */ D(A, { children: [/* @__PURE__ */ D(N, { children: [/* @__PURE__ */ D(P, {
306
484
  className: "flex items-center gap-2",
307
- children: [/* @__PURE__ */ w(b, {
485
+ children: [/* @__PURE__ */ E(S, {
486
+ className: "h-5 w-5",
487
+ "aria-hidden": "true"
488
+ }), "Tax-loss-harvesting opportunities"]
489
+ }), /* @__PURE__ */ E(M, { children: "Real unrealized-loss detection for the selected portfolio, using configurable dollar/percent thresholds and a wash-sale caution flag from your recorded transactions. Detection only — this never places a trade, and it is not tax advice." })] }), /* @__PURE__ */ D(j, {
490
+ className: "space-y-4",
491
+ children: [/* @__PURE__ */ D("div", {
492
+ className: "flex flex-wrap items-center gap-3",
493
+ children: [
494
+ /* @__PURE__ */ D(k, {
495
+ variant: "outline",
496
+ size: "sm",
497
+ disabled: !U || dt,
498
+ onClick: () => pt(),
499
+ children: [/* @__PURE__ */ E(be, {
500
+ className: "size-4",
501
+ "aria-hidden": "true"
502
+ }), "Recompute"]
503
+ }),
504
+ /* @__PURE__ */ D(k, {
505
+ variant: "outline",
506
+ size: "sm",
507
+ disabled: !U || (q?.opportunities.length ?? 0) === 0 || mt.isPending,
508
+ onClick: () => mt.mutate({ portfolioId: U }),
509
+ children: [/* @__PURE__ */ E(C, {
510
+ className: "size-4",
511
+ "aria-hidden": "true"
512
+ }), mt.isPending ? "Saving…" : "Save as insights"]
513
+ }),
514
+ q ? /* @__PURE__ */ D("span", {
515
+ className: "text-xs text-text-muted",
516
+ children: [
517
+ "Thresholds: ≥",
518
+ h(q.thresholds.minLossAmount),
519
+ " or ≥",
520
+ g(q.thresholds.minLossPct),
521
+ " of portfolio value"
522
+ ]
523
+ }) : null
524
+ ]
525
+ }), V.length === 0 ? /* @__PURE__ */ E(d, {
526
+ icon: /* @__PURE__ */ E(S, {
527
+ className: "size-6",
528
+ "aria-hidden": "true"
529
+ }),
530
+ title: "No portfolios yet",
531
+ description: "Create a portfolio to detect real tax-loss-harvesting opportunities from its holdings."
532
+ }) : dt ? /* @__PURE__ */ E(p, {}) : ft ? /* @__PURE__ */ E(f, { onRetry: () => pt() }) : q && q.opportunities.length > 0 ? /* @__PURE__ */ E("ul", {
533
+ className: "space-y-3",
534
+ children: q.opportunities.map((e) => /* @__PURE__ */ E(it, { opportunity: e }, e.symbol))
535
+ }) : q ? /* @__PURE__ */ E(d, {
536
+ icon: /* @__PURE__ */ E(w, {
537
+ className: "size-6",
538
+ "aria-hidden": "true"
539
+ }),
540
+ title: "No opportunities at the current thresholds",
541
+ description: "No symbol's unrealized loss clears the configured dollar/percent thresholds."
542
+ }) : /* @__PURE__ */ E(d, {
543
+ icon: /* @__PURE__ */ E(S, {
544
+ className: "size-6",
545
+ "aria-hidden": "true"
546
+ }),
547
+ title: "Select a portfolio",
548
+ description: "Choose a portfolio above to detect real tax-loss opportunities."
549
+ })]
550
+ })] }),
551
+ /* @__PURE__ */ D(A, { children: [/* @__PURE__ */ D(N, { children: [/* @__PURE__ */ D(P, {
552
+ className: "flex items-center gap-2",
553
+ children: [/* @__PURE__ */ E(x, {
308
554
  className: "h-5 w-5",
309
555
  "aria-hidden": "true"
310
556
  }), "Rebalance proposals"]
311
- }), /* @__PURE__ */ w(be, { children: "Drift against target allocation, with lifecycle actions per proposal." })] }), /* @__PURE__ */ w(ye, { children: d ? /* @__PURE__ */ w(ie, {}) : oe ? /* @__PURE__ */ w(re, { onRetry: () => se() }) : l.length === 0 ? /* @__PURE__ */ w(p, {
312
- icon: /* @__PURE__ */ w(b, {
557
+ }), /* @__PURE__ */ E(M, { children: "Drift against target allocation, with lifecycle actions per proposal." })] }), /* @__PURE__ */ E(j, { children: le ? /* @__PURE__ */ E(p, {}) : de ? /* @__PURE__ */ E(f, { onRetry: () => he() }) : c.length === 0 ? /* @__PURE__ */ E(d, {
558
+ icon: /* @__PURE__ */ E(x, {
313
559
  className: "size-6",
314
560
  "aria-hidden": "true"
315
561
  }),
316
562
  title: "No rebalance proposals",
317
- description: Q ? "Create a proposal when a portfolio drifts from its target allocation." : "Create a portfolio first, then propose a rebalance when it drifts.",
318
- action: Q ? /* @__PURE__ */ T(D, {
563
+ description: Bt ? "Create a proposal when a portfolio drifts from its target allocation." : "Create a portfolio first, then propose a rebalance when it drifts.",
564
+ action: Bt ? /* @__PURE__ */ D(k, {
319
565
  size: "sm",
320
- onClick: ht,
321
- children: [/* @__PURE__ */ w(he, {
566
+ onClick: Vt,
567
+ children: [/* @__PURE__ */ E(ye, {
322
568
  className: "size-4",
323
569
  "aria-hidden": "true"
324
570
  }), "New proposal"]
325
571
  }) : void 0
326
- }) : /* @__PURE__ */ w("div", {
572
+ }) : /* @__PURE__ */ E("div", {
327
573
  className: "overflow-x-auto",
328
- children: /* @__PURE__ */ T(ze, { children: [/* @__PURE__ */ w(Be, { children: /* @__PURE__ */ T(F, { children: [
329
- /* @__PURE__ */ w(P, { children: "Portfolio" }),
330
- /* @__PURE__ */ w(P, {
574
+ children: /* @__PURE__ */ D(He, { children: [/* @__PURE__ */ E(We, { children: /* @__PURE__ */ D(z, { children: [
575
+ /* @__PURE__ */ E(R, { children: "Portfolio" }),
576
+ /* @__PURE__ */ E(R, {
331
577
  className: "text-right",
332
578
  children: "Drift"
333
579
  }),
334
- /* @__PURE__ */ w(P, { children: "Status" }),
335
- /* @__PURE__ */ w(P, { children: "Rationale" }),
336
- /* @__PURE__ */ w(P, { children: "Trades" }),
337
- /* @__PURE__ */ w(P, { children: "Created" }),
338
- /* @__PURE__ */ w(P, {
580
+ /* @__PURE__ */ E(R, { children: "Status" }),
581
+ /* @__PURE__ */ E(R, { children: "Rationale" }),
582
+ /* @__PURE__ */ E(R, { children: "Trades" }),
583
+ /* @__PURE__ */ E(R, { children: "Created" }),
584
+ /* @__PURE__ */ E(R, {
339
585
  className: "w-12 text-right",
340
586
  children: "Actions"
341
587
  })
342
- ] }) }), /* @__PURE__ */ w(M, { children: l.map((e) => {
343
- let t = J.get(e.portfolioId), n = _t(e), r = He[e.status], i = t?.driftThresholdPct, a = i != null && i > 0 ? Math.min(100, e.driftPct / i * 100) : null;
344
- return /* @__PURE__ */ T(F, {
345
- onClick: () => G(e),
588
+ ] }) }), /* @__PURE__ */ E(Ue, { children: c.map((e) => {
589
+ let t = Q.get(e.portfolioId), n = Wt(e), r = Ke[e.status], i = t?.driftThresholdPct, a = i != null && i > 0 ? Math.min(100, e.driftPct / i * 100) : null;
590
+ return /* @__PURE__ */ D(z, {
591
+ onClick: () => jt(e),
346
592
  className: "cursor-pointer transition-colors motion-safe:hover:bg-bg-elevated",
347
593
  children: [
348
- /* @__PURE__ */ T(N, { children: [/* @__PURE__ */ w("p", {
594
+ /* @__PURE__ */ D(L, { children: [/* @__PURE__ */ E("p", {
349
595
  className: "font-medium text-text-primary",
350
596
  children: t?.name ?? "Unknown portfolio"
351
- }), /* @__PURE__ */ T("p", {
597
+ }), /* @__PURE__ */ D("p", {
352
598
  className: "text-xs text-text-secondary",
353
- children: [t?.baseCurrency ?? "—", i == null ? "" : ` · threshold ${h(i)}`]
599
+ children: [t?.baseCurrency ?? "—", i == null ? "" : ` · threshold ${g(i)}`]
354
600
  })] }),
355
- /* @__PURE__ */ T(N, {
601
+ /* @__PURE__ */ D(L, {
356
602
  className: "text-right",
357
- children: [/* @__PURE__ */ T("span", {
603
+ children: [/* @__PURE__ */ D("span", {
358
604
  className: `inline-flex items-center justify-end gap-1 font-semibold tabular-nums ${n ? "text-status-error-text" : "text-text-primary"}`,
359
- children: [n ? /* @__PURE__ */ w(le, {
605
+ children: [n ? /* @__PURE__ */ E(pe, {
360
606
  className: "size-4",
361
607
  "aria-hidden": "true"
362
- }) : null, h(e.driftPct)]
363
- }), a == null ? n ? /* @__PURE__ */ w("p", {
608
+ }) : null, g(e.driftPct)]
609
+ }), a == null ? n ? /* @__PURE__ */ E("p", {
364
610
  className: "text-xs text-status-error-text",
365
611
  children: "Over threshold"
366
- }) : null : /* @__PURE__ */ w("div", {
612
+ }) : null : /* @__PURE__ */ E("div", {
367
613
  className: "ml-auto mt-1 h-1.5 w-24 overflow-hidden rounded-full bg-bg-sunken",
368
614
  role: "progressbar",
369
615
  "aria-valuenow": Math.round(a),
370
616
  "aria-valuemin": 0,
371
617
  "aria-valuemax": 100,
372
618
  "aria-label": `Drift vs threshold for ${t?.name ?? "portfolio"}`,
373
- children: /* @__PURE__ */ w("div", {
619
+ children: /* @__PURE__ */ E("div", {
374
620
  className: "h-full rounded-full",
375
621
  style: {
376
622
  width: `${a}%`,
@@ -379,60 +625,60 @@ function $e() {
379
625
  })
380
626
  })]
381
627
  }),
382
- /* @__PURE__ */ w(N, { children: /* @__PURE__ */ w(E, {
383
- variant: g(e.status),
384
- children: I(e.status)
628
+ /* @__PURE__ */ E(L, { children: /* @__PURE__ */ E(O, {
629
+ variant: _(e.status),
630
+ children: B(e.status)
385
631
  }) }),
386
- /* @__PURE__ */ w(N, {
632
+ /* @__PURE__ */ E(L, {
387
633
  className: "max-w-xs",
388
- children: /* @__PURE__ */ w("p", {
634
+ children: /* @__PURE__ */ E("p", {
389
635
  className: "truncate text-sm text-text-secondary",
390
636
  children: e.rationale ?? "—"
391
637
  })
392
638
  }),
393
- /* @__PURE__ */ w(N, {
639
+ /* @__PURE__ */ E(L, {
394
640
  className: "text-sm text-text-secondary",
395
- children: Xe(e.trades)
641
+ children: $e(e.trades)
396
642
  }),
397
- /* @__PURE__ */ w(N, {
643
+ /* @__PURE__ */ E(L, {
398
644
  className: "text-sm text-text-secondary",
399
645
  children: m(e.createdAt)
400
646
  }),
401
- /* @__PURE__ */ w(N, {
647
+ /* @__PURE__ */ E(L, {
402
648
  className: "text-right",
403
649
  onClick: (e) => e.stopPropagation(),
404
- children: /* @__PURE__ */ T(Oe, { children: [/* @__PURE__ */ w(Me, {
650
+ children: /* @__PURE__ */ D(je, { children: [/* @__PURE__ */ E(Fe, {
405
651
  asChild: !0,
406
- children: /* @__PURE__ */ w(D, {
652
+ children: /* @__PURE__ */ E(k, {
407
653
  variant: "ghost",
408
654
  size: "sm",
409
655
  "aria-label": `Actions for ${t?.name ?? "proposal"}`,
410
- children: /* @__PURE__ */ w(me, {
656
+ children: /* @__PURE__ */ E(ve, {
411
657
  className: "size-4",
412
658
  "aria-hidden": "true"
413
659
  })
414
660
  })
415
- }), /* @__PURE__ */ T(ke, {
661
+ }), /* @__PURE__ */ D(Me, {
416
662
  align: "end",
417
- children: [/* @__PURE__ */ T(A, {
418
- onClick: () => G(e),
419
- children: [/* @__PURE__ */ w(de, {
663
+ children: [/* @__PURE__ */ D(F, {
664
+ onClick: () => jt(e),
665
+ children: [/* @__PURE__ */ E(ge, {
420
666
  className: "size-4",
421
667
  "aria-hidden": "true"
422
668
  }), "View details"]
423
- }), r.length > 0 ? /* @__PURE__ */ T(_e, { children: [
424
- /* @__PURE__ */ w(je, {}),
425
- /* @__PURE__ */ w(Ae, { children: "Advance to" }),
669
+ }), r.length > 0 ? /* @__PURE__ */ D(Ce, { children: [
670
+ /* @__PURE__ */ E(Pe, {}),
671
+ /* @__PURE__ */ E(Ne, { children: "Advance to" }),
426
672
  r.map((t) => {
427
673
  let n = t === "REJECTED" || t === "CANCELLED";
428
- return /* @__PURE__ */ T(A, {
429
- disabled: z.isPending,
674
+ return /* @__PURE__ */ D(F, {
675
+ disabled: J.isPending,
430
676
  className: n ? "text-status-error-text" : void 0,
431
- onClick: () => $(e, t),
432
- children: [w(n ? C : ue, {
677
+ onClick: () => Ut(e, t),
678
+ children: [E(n ? T : me, {
433
679
  className: "size-4",
434
680
  "aria-hidden": "true"
435
- }), I(t)]
681
+ }), B(t)]
436
682
  }, t);
437
683
  })
438
684
  ] }) : null]
@@ -442,79 +688,79 @@ function $e() {
442
688
  }, e.id);
443
689
  }) })] })
444
690
  }) })] }),
445
- /* @__PURE__ */ T(ve, { children: [/* @__PURE__ */ T(xe, { children: [/* @__PURE__ */ T(Se, {
691
+ /* @__PURE__ */ D(A, { children: [/* @__PURE__ */ D(N, { children: [/* @__PURE__ */ D(P, {
446
692
  className: "flex items-center gap-2",
447
- children: [/* @__PURE__ */ w(x, {
693
+ children: [/* @__PURE__ */ E(C, {
448
694
  className: "h-5 w-5",
449
695
  "aria-hidden": "true"
450
696
  }), "Risk insights"]
451
- }), /* @__PURE__ */ w(be, { children: "Drift, concentration, cash-drag and fee-anomaly signals detected across your portfolios." })] }), /* @__PURE__ */ w(ye, { children: $e ? /* @__PURE__ */ w(ie, {}) : rt ? /* @__PURE__ */ w(re, { onRetry: () => it() }) : Y.length === 0 ? /* @__PURE__ */ w(p, {
452
- icon: /* @__PURE__ */ w(S, {
697
+ }), /* @__PURE__ */ E(M, { children: "Drift, concentration, cash-drag and fee-anomaly signals detected across your portfolios." })] }), /* @__PURE__ */ E(j, { children: vt ? /* @__PURE__ */ E(p, {}) : bt ? /* @__PURE__ */ E(f, { onRetry: () => xt() }) : Nt.length === 0 ? /* @__PURE__ */ E(d, {
698
+ icon: /* @__PURE__ */ E(w, {
453
699
  className: "size-6",
454
700
  "aria-hidden": "true"
455
701
  }),
456
702
  title: "No risk insights",
457
703
  description: "No drift, concentration, cash-drag or fee-anomaly signals are open right now."
458
- }) : /* @__PURE__ */ T("div", {
704
+ }) : /* @__PURE__ */ D("div", {
459
705
  className: "space-y-3",
460
- children: [Y.map((e, t) => /* @__PURE__ */ w(u, {
706
+ children: [Nt.map((e, t) => /* @__PURE__ */ E(l, {
461
707
  index: t,
462
- children: /* @__PURE__ */ w(tt, {
708
+ children: /* @__PURE__ */ E(at, {
463
709
  insight: e,
464
- onAcknowledge: () => at.mutate(e.id),
465
- onResolve: () => st.mutate(e.id),
466
- onDismiss: () => ot.mutate(e.id),
467
- actionPending: at.isPending || st.isPending || ot.isPending
710
+ onAcknowledge: () => Ct.mutate(e.id),
711
+ onResolve: () => Tt.mutate(e.id),
712
+ onDismiss: () => wt.mutate(e.id),
713
+ actionPending: Ct.isPending || Tt.isPending || wt.isPending
468
714
  })
469
- }, e.id)), /* @__PURE__ */ w(c, {
470
- hasMore: Je,
471
- onClick: Ye,
472
- loading: nt,
715
+ }, e.id)), /* @__PURE__ */ E(ae, {
716
+ hasMore: gt,
717
+ onClick: _t,
718
+ loading: yt,
473
719
  label: "Load more insights"
474
720
  })]
475
721
  }) })] }),
476
- /* @__PURE__ */ w(Ce, {
477
- open: ct,
478
- onOpenChange: B,
479
- children: /* @__PURE__ */ T(O, { children: [
480
- /* @__PURE__ */ T(Ee, { children: [/* @__PURE__ */ w(De, { children: "New rebalance proposal" }), /* @__PURE__ */ w(k, { children: "Propose a rebalance for a portfolio that has drifted from its target allocation." })] }),
481
- Q ? /* @__PURE__ */ T("div", {
722
+ /* @__PURE__ */ E(we, {
723
+ open: Et,
724
+ onOpenChange: Dt,
725
+ children: /* @__PURE__ */ D(Ee, { children: [
726
+ /* @__PURE__ */ D(ke, { children: [/* @__PURE__ */ E(Ae, { children: "New rebalance proposal" }), /* @__PURE__ */ E(De, { children: "Propose a rebalance for a portfolio that has drifted from its target allocation." })] }),
727
+ Bt ? /* @__PURE__ */ D("div", {
482
728
  className: "grid gap-4",
483
729
  children: [
484
- /* @__PURE__ */ T("div", {
730
+ /* @__PURE__ */ D("div", {
485
731
  className: "grid gap-4 sm:grid-cols-2",
486
- children: [/* @__PURE__ */ T("div", {
732
+ children: [/* @__PURE__ */ D("div", {
487
733
  className: "space-y-2",
488
- children: [/* @__PURE__ */ T(j, {
734
+ children: [/* @__PURE__ */ D(I, {
489
735
  htmlFor: "prop-portfolio",
490
- children: ["Portfolio ", /* @__PURE__ */ w("span", {
736
+ children: ["Portfolio ", /* @__PURE__ */ E("span", {
491
737
  className: "text-status-error-text",
492
738
  children: "*"
493
739
  })]
494
- }), /* @__PURE__ */ T(Pe, {
495
- value: V.portfolioId,
496
- onValueChange: (e) => H((t) => ({
740
+ }), /* @__PURE__ */ D(Le, {
741
+ value: Y.portfolioId,
742
+ onValueChange: (e) => X((t) => ({
497
743
  ...t,
498
744
  portfolioId: e
499
745
  })),
500
- children: [/* @__PURE__ */ w(Le, {
746
+ children: [/* @__PURE__ */ E(Be, {
501
747
  id: "prop-portfolio",
502
- children: /* @__PURE__ */ w(Re, { placeholder: "Select a portfolio" })
503
- }), /* @__PURE__ */ w(Fe, { children: y.map((e) => /* @__PURE__ */ w(Ie, {
748
+ children: /* @__PURE__ */ E(Ve, { placeholder: "Select a portfolio" })
749
+ }), /* @__PURE__ */ E(Re, { children: V.map((e) => /* @__PURE__ */ E(ze, {
504
750
  value: e.id,
505
751
  children: e.name
506
752
  }, e.id)) })]
507
753
  })]
508
- }), /* @__PURE__ */ T("div", {
754
+ }), /* @__PURE__ */ D("div", {
509
755
  className: "space-y-2",
510
- children: [/* @__PURE__ */ w(j, {
756
+ children: [/* @__PURE__ */ E(I, {
511
757
  htmlFor: "prop-drift",
512
758
  children: "Drift %"
513
- }), /* @__PURE__ */ w(Ne, {
759
+ }), /* @__PURE__ */ E(Ie, {
514
760
  id: "prop-drift",
515
761
  type: "number",
516
- value: V.driftPct,
517
- onChange: (e) => H((t) => ({
762
+ value: Y.driftPct,
763
+ onChange: (e) => X((t) => ({
518
764
  ...t,
519
765
  driftPct: e.target.value
520
766
  })),
@@ -522,294 +768,294 @@ function $e() {
522
768
  })]
523
769
  })]
524
770
  }),
525
- /* @__PURE__ */ T("div", {
771
+ /* @__PURE__ */ D("div", {
526
772
  className: "space-y-2",
527
- children: [/* @__PURE__ */ w(j, {
773
+ children: [/* @__PURE__ */ E(I, {
528
774
  htmlFor: "prop-rationale",
529
775
  children: "Rationale"
530
- }), /* @__PURE__ */ w(Ve, {
776
+ }), /* @__PURE__ */ E(Ge, {
531
777
  id: "prop-rationale",
532
- value: V.rationale,
533
- onChange: (e) => H((t) => ({
778
+ value: Y.rationale,
779
+ onChange: (e) => X((t) => ({
534
780
  ...t,
535
781
  rationale: e.target.value
536
782
  })),
537
783
  placeholder: "Why is this rebalance needed?"
538
784
  })]
539
785
  }),
540
- /* @__PURE__ */ T("div", {
786
+ /* @__PURE__ */ D("div", {
541
787
  className: "space-y-2",
542
788
  children: [
543
- /* @__PURE__ */ w(j, {
789
+ /* @__PURE__ */ E(I, {
544
790
  htmlFor: "prop-trades",
545
791
  children: "Trades (JSON, optional)"
546
792
  }),
547
- /* @__PURE__ */ w(Ve, {
793
+ /* @__PURE__ */ E(Ge, {
548
794
  id: "prop-trades",
549
795
  className: "font-mono text-xs",
550
- value: V.trades,
796
+ value: Y.trades,
551
797
  onChange: (e) => {
552
- U(null), H((t) => ({
798
+ kt(null), X((t) => ({
553
799
  ...t,
554
800
  trades: e.target.value
555
801
  }));
556
802
  },
557
803
  placeholder: "e.g. [{\"symbol\":\"VOO\",\"action\":\"SELL\",\"quantity\":10}]"
558
804
  }),
559
- lt ? /* @__PURE__ */ w("p", {
805
+ Ot ? /* @__PURE__ */ E("p", {
560
806
  className: "text-xs text-status-error-text",
561
- children: lt
807
+ children: Ot
562
808
  }) : null
563
809
  ]
564
810
  })
565
811
  ]
566
- }) : /* @__PURE__ */ w(p, {
567
- icon: /* @__PURE__ */ w(b, {
812
+ }) : /* @__PURE__ */ E(d, {
813
+ icon: /* @__PURE__ */ E(x, {
568
814
  className: "size-6",
569
815
  "aria-hidden": "true"
570
816
  }),
571
817
  title: "Create a portfolio first",
572
818
  description: "A rebalance proposal targets a portfolio. Add a portfolio on the Portfolios page, then return here to propose a rebalance."
573
819
  }),
574
- /* @__PURE__ */ T(Te, { children: [/* @__PURE__ */ w(we, {
820
+ /* @__PURE__ */ D(Oe, { children: [/* @__PURE__ */ E(Te, {
575
821
  asChild: !0,
576
- children: /* @__PURE__ */ w(D, {
822
+ children: /* @__PURE__ */ E(k, {
577
823
  variant: "outline",
578
824
  children: "Cancel"
579
825
  })
580
- }), /* @__PURE__ */ w(D, {
581
- onClick: gt,
582
- disabled: !V.portfolioId || R.isPending,
583
- children: R.isPending ? "Creating…" : "Create proposal"
826
+ }), /* @__PURE__ */ E(k, {
827
+ onClick: Ht,
828
+ disabled: !Y.portfolioId || St.isPending,
829
+ children: St.isPending ? "Creating…" : "Create proposal"
584
830
  })] })
585
831
  ] })
586
832
  }),
587
833
  (() => {
588
- let e = W ? l.find((e) => e.id === W.id) ?? W : null, t = e ? L.filter((t) => t.subjectId === e.portfolioId) : [];
589
- return /* @__PURE__ */ w(et, {
834
+ let e = At ? c.find((e) => e.id === At.id) ?? At : null, t = e ? ht.filter((t) => t.subjectId === e.portfolioId) : [];
835
+ return /* @__PURE__ */ E(nt, {
590
836
  proposal: e,
591
- portfolio: e ? J.get(e.portfolioId) ?? null : null,
837
+ portfolio: e ? Q.get(e.portfolioId) ?? null : null,
592
838
  relatedInsights: t,
593
- nextStatuses: e ? He[e.status] : [],
594
- transitionPending: z.isPending,
839
+ nextStatuses: e ? Ke[e.status] : [],
840
+ transitionPending: J.isPending,
595
841
  onTransition: (t) => {
596
- e && $(e, t);
842
+ e && Ut(e, t);
597
843
  },
598
844
  onOpenChange: (e) => {
599
- e || G(null);
845
+ e || jt(null);
600
846
  }
601
847
  });
602
848
  })(),
603
- /* @__PURE__ */ w(ee, {
604
- open: K !== null,
849
+ /* @__PURE__ */ E(oe, {
850
+ open: Z !== null,
605
851
  onOpenChange: (e) => {
606
- e || q(null);
852
+ e || Mt(null);
607
853
  },
608
- title: K?.status === "REJECTED" ? "Reject this proposal?" : "Cancel this proposal?",
609
- description: K ? `This moves the rebalance proposal for ${J.get(K.proposal.portfolioId)?.name ?? "this portfolio"} to ${I(K.status)}. This cannot be undone.` : void 0,
610
- confirmLabel: K?.status === "REJECTED" ? "Reject" : "Cancel proposal",
854
+ title: Z?.status === "REJECTED" ? "Reject this proposal?" : "Cancel this proposal?",
855
+ description: Z ? `This moves the rebalance proposal for ${Q.get(Z.proposal.portfolioId)?.name ?? "this portfolio"} to ${B(Z.status)}. This cannot be undone.` : void 0,
856
+ confirmLabel: Z?.status === "REJECTED" ? "Reject" : "Cancel proposal",
611
857
  cancelLabel: "Keep",
612
858
  destructive: !0,
613
- pending: z.isPending,
859
+ pending: J.isPending,
614
860
  onConfirm: () => {
615
- K && z.mutate({
616
- id: K.proposal.id,
617
- status: K.status
618
- }, { onSuccess: () => q(null) });
861
+ Z && J.mutate({
862
+ id: Z.proposal.id,
863
+ status: Z.status
864
+ }, { onSuccess: () => Mt(null) });
619
865
  }
620
866
  })
621
867
  ]
622
868
  });
623
869
  }
624
- function et({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, transitionPending: i, onTransition: a, onOpenChange: o }) {
625
- let s = e ? Je(e.trades) : null, c = e != null && t?.driftThresholdPct != null && Number.isFinite(t.driftThresholdPct) && e.driftPct >= t.driftThresholdPct;
626
- return /* @__PURE__ */ w(Ce, {
870
+ function nt({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, transitionPending: i, onTransition: a, onOpenChange: o }) {
871
+ let s = e ? Qe(e.trades) : null, ee = e != null && t?.driftThresholdPct != null && Number.isFinite(t.driftThresholdPct) && e.driftPct >= t.driftThresholdPct;
872
+ return /* @__PURE__ */ E(we, {
627
873
  open: e !== null,
628
874
  onOpenChange: o,
629
- children: /* @__PURE__ */ w(O, {
875
+ children: /* @__PURE__ */ E(Ee, {
630
876
  className: "max-h-[88vh] max-w-3xl overflow-y-auto",
631
- children: e ? /* @__PURE__ */ T(_e, { children: [
632
- /* @__PURE__ */ T(Ee, { children: [
633
- /* @__PURE__ */ w("p", {
877
+ children: e ? /* @__PURE__ */ D(Ce, { children: [
878
+ /* @__PURE__ */ D(ke, { children: [
879
+ /* @__PURE__ */ E("p", {
634
880
  className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
635
881
  children: "Detail"
636
882
  }),
637
- /* @__PURE__ */ T(De, {
883
+ /* @__PURE__ */ D(Ae, {
638
884
  className: "flex flex-wrap items-center gap-2 text-xl",
639
885
  children: [
640
886
  t?.name ?? "Rebalance proposal",
641
- /* @__PURE__ */ w("span", {
887
+ /* @__PURE__ */ E("span", {
642
888
  className: "text-text-secondary",
643
889
  children: "— Rebalance proposal"
644
890
  }),
645
- /* @__PURE__ */ w(E, {
646
- variant: g(e.status),
647
- children: I(e.status)
891
+ /* @__PURE__ */ E(O, {
892
+ variant: _(e.status),
893
+ children: B(e.status)
648
894
  })
649
895
  ]
650
896
  }),
651
- /* @__PURE__ */ T(k, { children: [
897
+ /* @__PURE__ */ D(De, { children: [
652
898
  "Created ",
653
899
  m(e.createdAt),
654
900
  e.executedAt ? ` · executed ${m(e.executedAt)}` : ""
655
901
  ] })
656
902
  ] }),
657
- /* @__PURE__ */ w("div", {
903
+ /* @__PURE__ */ E("div", {
658
904
  className: "rounded-xl border border-border-subtle bg-bg-surface p-4",
659
- children: /* @__PURE__ */ w(d, {
660
- steps: L,
661
- current: I(e.status)
905
+ children: /* @__PURE__ */ E(le, {
906
+ steps: V,
907
+ current: B(e.status)
662
908
  })
663
909
  }),
664
- /* @__PURE__ */ T("div", {
910
+ /* @__PURE__ */ D("div", {
665
911
  className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-4",
666
912
  children: [
667
- /* @__PURE__ */ w(f, {
913
+ /* @__PURE__ */ E(u, {
668
914
  label: "Drift",
669
- value: h(e.driftPct),
670
- deltaTone: c ? "negative" : "neutral",
671
- glow: c,
672
- icon: /* @__PURE__ */ w(fe, {
915
+ value: g(e.driftPct),
916
+ deltaTone: ee ? "negative" : "neutral",
917
+ glow: ee,
918
+ icon: /* @__PURE__ */ E(b, {
673
919
  className: "size-4",
674
920
  "aria-hidden": "true"
675
921
  })
676
922
  }),
677
- /* @__PURE__ */ w(f, {
923
+ /* @__PURE__ */ E(u, {
678
924
  label: "Threshold",
679
- value: t?.driftThresholdPct == null ? "—" : h(t.driftThresholdPct)
925
+ value: t?.driftThresholdPct == null ? "—" : g(t.driftThresholdPct)
680
926
  }),
681
- /* @__PURE__ */ T("div", {
927
+ /* @__PURE__ */ D("div", {
682
928
  className: "rounded-xl border border-border-subtle bg-bg-surface p-4",
683
- children: [/* @__PURE__ */ w("p", {
929
+ children: [/* @__PURE__ */ E("p", {
684
930
  className: "text-xs text-text-secondary",
685
931
  children: "Proposed by"
686
- }), /* @__PURE__ */ w("p", {
932
+ }), /* @__PURE__ */ E("p", {
687
933
  className: "mt-1 truncate text-sm font-medium text-text-primary",
688
- children: e.proposedById ? /* @__PURE__ */ w(l, { id: e.proposedById }) : "—"
934
+ children: e.proposedById ? /* @__PURE__ */ E(c, { id: e.proposedById }) : "—"
689
935
  })]
690
936
  }),
691
- /* @__PURE__ */ T("div", {
937
+ /* @__PURE__ */ D("div", {
692
938
  className: "rounded-xl border border-border-subtle bg-bg-surface p-4",
693
- children: [/* @__PURE__ */ w("p", {
939
+ children: [/* @__PURE__ */ E("p", {
694
940
  className: "text-xs text-text-secondary",
695
941
  children: "Approved by"
696
- }), /* @__PURE__ */ w("p", {
942
+ }), /* @__PURE__ */ E("p", {
697
943
  className: "mt-1 truncate text-sm font-medium text-text-primary",
698
- children: e.approvedById ? /* @__PURE__ */ w(l, { id: e.approvedById }) : "—"
944
+ children: e.approvedById ? /* @__PURE__ */ E(c, { id: e.approvedById }) : "—"
699
945
  })]
700
946
  })
701
947
  ]
702
948
  }),
703
- /* @__PURE__ */ T("div", {
949
+ /* @__PURE__ */ D("div", {
704
950
  className: "space-y-2",
705
- children: [/* @__PURE__ */ w("h3", {
951
+ children: [/* @__PURE__ */ E("h3", {
706
952
  className: "text-sm font-semibold text-text-primary",
707
953
  children: "Proposed trades"
708
- }), s && s.length > 0 ? /* @__PURE__ */ w("div", {
954
+ }), s && s.length > 0 ? /* @__PURE__ */ E("div", {
709
955
  className: "overflow-x-auto rounded-lg border border-border-subtle",
710
- children: /* @__PURE__ */ T(ze, { children: [/* @__PURE__ */ w(Be, { children: /* @__PURE__ */ T(F, { children: [
711
- /* @__PURE__ */ w(P, { children: "Action" }),
712
- /* @__PURE__ */ w(P, { children: "Symbol" }),
713
- /* @__PURE__ */ w(P, {
956
+ children: /* @__PURE__ */ D(He, { children: [/* @__PURE__ */ E(We, { children: /* @__PURE__ */ D(z, { children: [
957
+ /* @__PURE__ */ E(R, { children: "Action" }),
958
+ /* @__PURE__ */ E(R, { children: "Symbol" }),
959
+ /* @__PURE__ */ E(R, {
714
960
  className: "text-right",
715
961
  children: "Quantity"
716
962
  }),
717
- /* @__PURE__ */ w(P, {
963
+ /* @__PURE__ */ E(R, {
718
964
  className: "text-right",
719
965
  children: "Est. value"
720
966
  })
721
- ] }) }), /* @__PURE__ */ w(M, { children: s.map((e, n) => /* @__PURE__ */ T(F, { children: [
722
- /* @__PURE__ */ w(N, {
723
- className: `font-semibold ${Ye(e.action)}`,
967
+ ] }) }), /* @__PURE__ */ E(Ue, { children: s.map((e, n) => /* @__PURE__ */ D(z, { children: [
968
+ /* @__PURE__ */ E(L, {
969
+ className: `font-semibold ${U(e.action)}`,
724
970
  children: e.action ? e.action.toUpperCase() : "—"
725
971
  }),
726
- /* @__PURE__ */ w(N, {
972
+ /* @__PURE__ */ E(L, {
727
973
  className: "font-medium text-text-primary",
728
974
  children: e.symbol ?? "—"
729
975
  }),
730
- /* @__PURE__ */ w(N, {
976
+ /* @__PURE__ */ E(L, {
731
977
  className: "text-right tabular-nums text-text-secondary",
732
978
  children: e.quantity == null ? "—" : e.quantity.toLocaleString()
733
979
  }),
734
- /* @__PURE__ */ w(N, {
980
+ /* @__PURE__ */ E(L, {
735
981
  className: "text-right tabular-nums text-text-secondary",
736
- children: e.value == null ? "—" : oe(e.value, t?.baseCurrency ?? "USD")
982
+ children: e.value == null ? "—" : h(e.value, t?.baseCurrency ?? "USD")
737
983
  })
738
984
  ] }, n)) })] })
739
- }) : /* @__PURE__ */ T("p", {
985
+ }) : /* @__PURE__ */ D("p", {
740
986
  className: "text-sm text-text-secondary",
741
- children: [Xe(e.trades), " — no structured trade breakdown available."]
987
+ children: [$e(e.trades), " — no structured trade breakdown available."]
742
988
  })]
743
989
  }),
744
- /* @__PURE__ */ T("div", {
990
+ /* @__PURE__ */ D("div", {
745
991
  className: "space-y-1",
746
- children: [/* @__PURE__ */ w("h3", {
992
+ children: [/* @__PURE__ */ E("h3", {
747
993
  className: "text-sm font-semibold text-text-primary",
748
994
  children: "Rationale"
749
- }), /* @__PURE__ */ w("p", {
995
+ }), /* @__PURE__ */ E("p", {
750
996
  className: "text-sm text-text-secondary",
751
997
  children: e.rationale ?? "—"
752
998
  })]
753
999
  }),
754
- r.length > 0 ? /* @__PURE__ */ w("div", {
1000
+ r.length > 0 ? /* @__PURE__ */ E("div", {
755
1001
  className: "flex flex-wrap gap-2",
756
1002
  children: r.map((e) => {
757
1003
  let t = e === "REJECTED" || e === "CANCELLED";
758
- return /* @__PURE__ */ T(D, {
1004
+ return /* @__PURE__ */ D(k, {
759
1005
  variant: t ? "outline" : "default",
760
1006
  size: "sm",
761
1007
  disabled: i,
762
1008
  className: t ? "text-status-error-text" : void 0,
763
1009
  onClick: () => a(e),
764
- children: [w(t ? C : ue, {
1010
+ children: [E(t ? T : me, {
765
1011
  className: "size-4",
766
1012
  "aria-hidden": "true"
767
- }), I(e)]
1013
+ }), B(e)]
768
1014
  }, e);
769
1015
  })
770
1016
  }) : null,
771
- n.length > 0 ? /* @__PURE__ */ T("div", {
1017
+ n.length > 0 ? /* @__PURE__ */ D("div", {
772
1018
  className: "space-y-2 border-t border-border-subtle pt-4",
773
- children: [/* @__PURE__ */ T("h3", {
1019
+ children: [/* @__PURE__ */ D("h3", {
774
1020
  className: "flex items-center gap-2 text-sm font-semibold text-text-primary",
775
- children: [/* @__PURE__ */ w(x, {
1021
+ children: [/* @__PURE__ */ E(C, {
776
1022
  className: "size-4",
777
1023
  "aria-hidden": "true"
778
1024
  }), "Risk insights"]
779
- }), /* @__PURE__ */ w("ul", {
1025
+ }), /* @__PURE__ */ E("ul", {
780
1026
  className: "space-y-2",
781
- children: n.map((e) => /* @__PURE__ */ T("li", {
1027
+ children: n.map((e) => /* @__PURE__ */ D("li", {
782
1028
  className: "rounded-lg border border-border-subtle bg-bg-surface p-3",
783
- children: [/* @__PURE__ */ T("div", {
1029
+ children: [/* @__PURE__ */ D("div", {
784
1030
  className: "flex flex-wrap items-center gap-2",
785
1031
  children: [
786
- /* @__PURE__ */ w("span", {
1032
+ /* @__PURE__ */ E("span", {
787
1033
  className: "text-sm font-medium text-text-primary",
788
1034
  children: e.title
789
1035
  }),
790
- /* @__PURE__ */ w(E, {
791
- variant: g(e.severity),
792
- children: I(e.severity)
1036
+ /* @__PURE__ */ E(O, {
1037
+ variant: _(e.severity),
1038
+ children: B(e.severity)
793
1039
  }),
794
- /* @__PURE__ */ w(E, {
1040
+ /* @__PURE__ */ E(O, {
795
1041
  variant: "outline",
796
- children: I(e.type)
1042
+ children: B(e.type)
797
1043
  }),
798
- /* @__PURE__ */ w(E, {
799
- variant: g(e.status),
800
- children: I(e.status)
1044
+ /* @__PURE__ */ E(O, {
1045
+ variant: _(e.status),
1046
+ children: B(e.status)
801
1047
  })
802
1048
  ]
803
- }), e.detail ? /* @__PURE__ */ w("p", {
1049
+ }), e.detail ? /* @__PURE__ */ E("p", {
804
1050
  className: "mt-1 text-xs text-text-secondary",
805
1051
  children: e.detail
806
1052
  }) : null]
807
1053
  }, e.id))
808
1054
  })]
809
1055
  }) : null,
810
- /* @__PURE__ */ w("div", {
1056
+ /* @__PURE__ */ E("div", {
811
1057
  className: "border-t border-border-subtle pt-4",
812
- children: /* @__PURE__ */ w(se, {
1058
+ children: /* @__PURE__ */ E(de, {
813
1059
  entityType: "brainyrich-rebalance",
814
1060
  entityId: e.id,
815
1061
  heading: "Discussion"
@@ -819,79 +1065,183 @@ function et({ proposal: e, portfolio: t, relatedInsights: n, nextStatuses: r, tr
819
1065
  })
820
1066
  });
821
1067
  }
822
- function tt({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPending: i }) {
1068
+ function rt({ signal: e }) {
1069
+ let t = Object.entries(e.metrics ?? {});
1070
+ return /* @__PURE__ */ D("li", {
1071
+ className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
1072
+ children: [
1073
+ /* @__PURE__ */ D("div", {
1074
+ className: "flex flex-wrap items-center gap-2",
1075
+ children: [
1076
+ /* @__PURE__ */ E("p", {
1077
+ className: "font-medium text-text-primary",
1078
+ children: e.title
1079
+ }),
1080
+ /* @__PURE__ */ E(O, {
1081
+ variant: _(e.severity),
1082
+ children: B(e.severity)
1083
+ }),
1084
+ /* @__PURE__ */ E(O, {
1085
+ variant: "outline",
1086
+ children: B(e.kind)
1087
+ })
1088
+ ]
1089
+ }),
1090
+ e.detail ? /* @__PURE__ */ E("p", {
1091
+ className: "mt-1 text-sm text-text-secondary",
1092
+ children: e.detail
1093
+ }) : null,
1094
+ t.length > 0 ? /* @__PURE__ */ E("dl", {
1095
+ className: "mt-3 grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-3 lg:grid-cols-4",
1096
+ children: t.map(([e, t]) => /* @__PURE__ */ D("div", {
1097
+ className: "min-w-0",
1098
+ children: [/* @__PURE__ */ E("dt", {
1099
+ className: "truncate text-[11px] uppercase tracking-wide text-text-muted",
1100
+ children: B(e)
1101
+ }), /* @__PURE__ */ E("dd", {
1102
+ className: "truncate text-sm font-medium tabular-nums text-text-primary",
1103
+ children: H(t)
1104
+ })]
1105
+ }, e))
1106
+ }) : null
1107
+ ]
1108
+ });
1109
+ }
1110
+ function it({ opportunity: e }) {
1111
+ let t = Object.entries(e.metrics ?? {});
1112
+ return /* @__PURE__ */ D("li", {
1113
+ className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
1114
+ children: [
1115
+ /* @__PURE__ */ D("div", {
1116
+ className: "flex flex-wrap items-center gap-2",
1117
+ children: [
1118
+ /* @__PURE__ */ D("p", {
1119
+ className: "font-medium text-text-primary",
1120
+ children: [
1121
+ e.symbol,
1122
+ " — unrealized loss ",
1123
+ h(e.unrealizedLoss)
1124
+ ]
1125
+ }),
1126
+ /* @__PURE__ */ E(O, {
1127
+ variant: _(e.severity),
1128
+ children: B(e.severity)
1129
+ }),
1130
+ e.washSaleRisk ? /* @__PURE__ */ D(O, {
1131
+ variant: "outline",
1132
+ className: "text-status-error-text",
1133
+ children: [/* @__PURE__ */ E(pe, {
1134
+ className: "mr-1 size-3",
1135
+ "aria-hidden": "true"
1136
+ }), "Wash-sale caution"]
1137
+ }) : null
1138
+ ]
1139
+ }),
1140
+ /* @__PURE__ */ D("p", {
1141
+ className: "mt-1 text-sm text-text-secondary",
1142
+ children: [
1143
+ "Market value ",
1144
+ h(e.marketValue),
1145
+ " vs. cost basis ",
1146
+ h(e.costBasis),
1147
+ " · ",
1148
+ g(e.lossPctOfPortfolio),
1149
+ " of portfolio value"
1150
+ ]
1151
+ }),
1152
+ e.washSaleReason ? /* @__PURE__ */ E("p", {
1153
+ className: "mt-1 text-xs text-status-error-text",
1154
+ children: e.washSaleReason
1155
+ }) : null,
1156
+ t.length > 0 ? /* @__PURE__ */ E("dl", {
1157
+ className: "mt-3 grid grid-cols-2 gap-x-4 gap-y-1 sm:grid-cols-3 lg:grid-cols-4",
1158
+ children: t.filter(([e]) => e !== "formula").map(([e, t]) => /* @__PURE__ */ D("div", {
1159
+ className: "min-w-0",
1160
+ children: [/* @__PURE__ */ E("dt", {
1161
+ className: "truncate text-[11px] uppercase tracking-wide text-text-muted",
1162
+ children: B(e)
1163
+ }), /* @__PURE__ */ E("dd", {
1164
+ className: "truncate text-sm font-medium tabular-nums text-text-primary",
1165
+ children: H(t)
1166
+ })]
1167
+ }, e))
1168
+ }) : null
1169
+ ]
1170
+ });
1171
+ }
1172
+ function at({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPending: i }) {
823
1173
  let a = e.status === "RESOLVED" || e.status === "DISMISSED";
824
- return /* @__PURE__ */ T("div", {
1174
+ return /* @__PURE__ */ D("div", {
825
1175
  className: "flex items-start justify-between gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4 transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]",
826
- children: [/* @__PURE__ */ T("div", {
1176
+ children: [/* @__PURE__ */ D("div", {
827
1177
  className: "min-w-0 space-y-1",
828
1178
  children: [
829
- /* @__PURE__ */ T("div", {
1179
+ /* @__PURE__ */ D("div", {
830
1180
  className: "flex flex-wrap items-center gap-2",
831
1181
  children: [
832
- /* @__PURE__ */ w("p", {
1182
+ /* @__PURE__ */ E("p", {
833
1183
  className: "font-medium text-text-primary",
834
1184
  children: e.title
835
1185
  }),
836
- /* @__PURE__ */ w(E, {
837
- variant: g(e.severity),
838
- children: I(e.severity)
1186
+ /* @__PURE__ */ E(O, {
1187
+ variant: _(e.severity),
1188
+ children: B(e.severity)
839
1189
  }),
840
- /* @__PURE__ */ w(E, {
1190
+ /* @__PURE__ */ E(O, {
841
1191
  variant: "outline",
842
- children: I(e.type)
1192
+ children: B(e.type)
843
1193
  }),
844
- /* @__PURE__ */ w(E, {
845
- variant: g(e.status),
846
- children: I(e.status)
1194
+ /* @__PURE__ */ E(O, {
1195
+ variant: _(e.status),
1196
+ children: B(e.status)
847
1197
  })
848
1198
  ]
849
1199
  }),
850
- e.detail ? /* @__PURE__ */ w("p", {
1200
+ e.detail ? /* @__PURE__ */ E("p", {
851
1201
  className: "text-sm text-text-secondary",
852
1202
  children: e.detail
853
1203
  }) : null,
854
- /* @__PURE__ */ T("p", {
1204
+ /* @__PURE__ */ D("p", {
855
1205
  className: "text-xs text-text-muted",
856
1206
  children: ["Detected ", m(e.createdAt)]
857
1207
  })
858
1208
  ]
859
- }), a ? /* @__PURE__ */ w("span", {
1209
+ }), a ? /* @__PURE__ */ E("span", {
860
1210
  className: "mt-1 text-xs text-text-muted",
861
1211
  children: "Closed"
862
- }) : /* @__PURE__ */ T(Oe, { children: [/* @__PURE__ */ w(Me, {
1212
+ }) : /* @__PURE__ */ D(je, { children: [/* @__PURE__ */ E(Fe, {
863
1213
  asChild: !0,
864
- children: /* @__PURE__ */ w(D, {
1214
+ children: /* @__PURE__ */ E(k, {
865
1215
  variant: "ghost",
866
1216
  size: "sm",
867
1217
  "aria-label": `Actions for ${e.title}`,
868
1218
  disabled: i,
869
- children: /* @__PURE__ */ w(me, {
1219
+ children: /* @__PURE__ */ E(ve, {
870
1220
  className: "size-4",
871
1221
  "aria-hidden": "true"
872
1222
  })
873
1223
  })
874
- }), /* @__PURE__ */ T(ke, {
1224
+ }), /* @__PURE__ */ D(Me, {
875
1225
  align: "end",
876
1226
  children: [
877
- e.status === "OPEN" ? /* @__PURE__ */ T(A, {
1227
+ e.status === "OPEN" ? /* @__PURE__ */ D(F, {
878
1228
  onClick: t,
879
- children: [/* @__PURE__ */ w(y, {
1229
+ children: [/* @__PURE__ */ E(he, {
880
1230
  className: "size-4",
881
1231
  "aria-hidden": "true"
882
1232
  }), "Acknowledge"]
883
1233
  }) : null,
884
- /* @__PURE__ */ T(A, {
1234
+ /* @__PURE__ */ D(F, {
885
1235
  onClick: n,
886
- children: [/* @__PURE__ */ w(S, {
1236
+ children: [/* @__PURE__ */ E(w, {
887
1237
  className: "size-4",
888
1238
  "aria-hidden": "true"
889
1239
  }), "Resolve"]
890
1240
  }),
891
- /* @__PURE__ */ T(A, {
1241
+ /* @__PURE__ */ D(F, {
892
1242
  className: "text-status-error-text",
893
1243
  onClick: r,
894
- children: [/* @__PURE__ */ w(C, {
1244
+ children: [/* @__PURE__ */ E(T, {
895
1245
  className: "size-4",
896
1246
  "aria-hidden": "true"
897
1247
  }), "Dismiss"]
@@ -901,6 +1251,6 @@ function tt({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPe
901
1251
  });
902
1252
  }
903
1253
  //#endregion
904
- export { $e as RiskPage };
1254
+ export { W as RiskPage };
905
1255
 
906
1256
  //# sourceMappingURL=RiskPage.js.map