@paro.io/expert-shared-components 1.14.53 → 1.14.55

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 (26) hide show
  1. package/lib/components/TaxAxis/TaxAxisApi.d.ts +2 -0
  2. package/lib/components/TaxAxis/TaxAxisShell.js +138 -13
  3. package/lib/tax-axis/components/clientReport/ExecutiveSummary.d.ts +4 -1
  4. package/lib/tax-axis/components/clientReport/ExecutiveSummary.js +10 -6
  5. package/lib/tax-axis/components/clientReport/RecommendedStrategies.d.ts +6 -1
  6. package/lib/tax-axis/components/clientReport/RecommendedStrategies.js +26 -24
  7. package/lib/tax-axis/components/clientReport/StrategyCard.d.ts +1 -1
  8. package/lib/tax-axis/components/clientReport/StrategyCard.js +39 -23
  9. package/lib/tax-axis/components/clientReport/TaxAxisClientReport.d.ts +3 -1
  10. package/lib/tax-axis/components/clientReport/TaxAxisClientReport.js +4 -4
  11. package/lib/tax-axis/components/dashboard/DashboardSummary.d.ts +6 -1
  12. package/lib/tax-axis/components/dashboard/DashboardSummary.js +14 -4
  13. package/lib/tax-axis/components/dashboard/StrategyDetailPanel.d.ts +1 -1
  14. package/lib/tax-axis/components/dashboard/StrategyDetailPanel.js +123 -91
  15. package/lib/tax-axis/components/dashboard/TaxAxisDashboard.d.ts +3 -2
  16. package/lib/tax-axis/components/dashboard/TaxAxisDashboard.js +67 -19
  17. package/lib/tax-axis/components/documents/TaxAxisDocuments.d.ts +2 -0
  18. package/lib/tax-axis/components/documents/TaxAxisDocuments.js +46 -10
  19. package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.d.ts +21 -1
  20. package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.js +10 -1
  21. package/lib/tax-axis/components/processing/TaxAxisProcessing.d.ts +3 -1
  22. package/lib/tax-axis/components/processing/TaxAxisProcessing.js +77 -31
  23. package/lib/tax-axis/lib/adapters/useEngineOutput.d.ts +7 -0
  24. package/lib/tax-axis/lib/adapters/useEngineOutput.js +10 -4
  25. package/lib/tax-axis/lib/types/index.d.ts +10 -1
  26. package/package.json +1 -1
@@ -6,10 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.DashboardSummary = DashboardSummary;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const useCountUp_1 = require("./useCountUp");
9
- function DashboardSummary({ profile, dashEligible, computed, dataConfirmed, reviewUnreviewed, }) {
9
+ function DashboardSummary({ profile, dashEligible, computed, dataConfirmed, reviewUnreviewed, liveSavingsMin, liveSavingsMax, liveStrategyCount, confidenceTier, dataYears, }) {
10
10
  var _a;
11
- const totalLo = dashEligible.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.lo) !== null && _b !== void 0 ? _b : s.lo); }, 0);
12
- const totalHi = dashEligible.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.hi) !== null && _b !== void 0 ? _b : s.hi); }, 0);
11
+ const computedLo = dashEligible.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.lo) !== null && _b !== void 0 ? _b : s.lo); }, 0);
12
+ const computedHi = dashEligible.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.hi) !== null && _b !== void 0 ? _b : s.hi); }, 0);
13
+ const totalLo = liveSavingsMin !== null && liveSavingsMin !== void 0 ? liveSavingsMin : computedLo;
14
+ const totalHi = liveSavingsMax !== null && liveSavingsMax !== void 0 ? liveSavingsMax : computedHi;
15
+ const strategyCount = liveStrategyCount !== null && liveStrategyCount !== void 0 ? liveStrategyCount : dashEligible.length;
13
16
  const bizName = profile.bizName || "Client";
14
17
  const stateCount = ((_a = profile.states) === null || _a === void 0 ? void 0 : _a.length) || 1;
15
18
  const scoreAvg = Math.round(dashEligible.reduce((a, s) => a + s.score, 0) / (dashEligible.length || 1));
@@ -78,7 +81,7 @@ function DashboardSummary({ profile, dashEligible, computed, dataConfirmed, revi
78
81
  profile.cpaName)),
79
82
  react_1.default.createElement("div", { className: "flex gap-6 mt-[22px] pt-[18px]", style: { borderTop: "1px solid rgba(36,131,132,0.12)" } }, [
80
83
  { v: String(scoreUp), u: "/100", l: "Avg. Confidence", warn: false, ok: false },
81
- { v: String(dashEligible.length), u: "", l: "Strategies Identified", warn: false, ok: false },
84
+ { v: String(strategyCount), u: "", l: "Strategies Identified", warn: false, ok: false },
82
85
  {
83
86
  v: dataConfirmed ? "Done" : String(reviewUnreviewed),
84
87
  u: "",
@@ -86,6 +89,13 @@ function DashboardSummary({ profile, dashEligible, computed, dataConfirmed, revi
86
89
  warn: !dataConfirmed && reviewUnreviewed > 0,
87
90
  ok: dataConfirmed,
88
91
  },
92
+ ...(confidenceTier ? [{
93
+ v: dataYears ? String(dataYears) : "1",
94
+ u: "yr",
95
+ l: confidenceTier.replace(/-DATA$/, "").replace(/-/g, " ").replace(/YR/, "yr"),
96
+ warn: (dataYears !== null && dataYears !== void 0 ? dataYears : 1) < 2,
97
+ ok: (dataYears !== null && dataYears !== void 0 ? dataYears : 1) >= 3,
98
+ }] : []),
89
99
  ].map(({ v, u, l, warn, ok }) => (react_1.default.createElement("div", { key: l },
90
100
  react_1.default.createElement("div", { className: "font-tax-axis-mono font-bold leading-none", style: {
91
101
  fontSize: 24,
@@ -6,5 +6,5 @@ interface StrategyDetailPanelProps {
6
6
  computed: ComputedMap;
7
7
  onClose: () => void;
8
8
  }
9
- export declare function StrategyDetailPanel({ s, profile, computed, onClose }: StrategyDetailPanelProps): React.JSX.Element;
9
+ export declare function StrategyDetailPanel({ s, profile: _profile, computed, onClose }: StrategyDetailPanelProps): React.JSX.Element;
10
10
  export {};
@@ -5,26 +5,105 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.StrategyDetailPanel = StrategyDetailPanel;
7
7
  const react_1 = __importDefault(require("react"));
8
- const data_1 = require("../../lib/data");
9
8
  const TaxAxisBadge_1 = require("../shared/TaxAxisBadge");
10
- function Sec({ title, children }) {
9
+ function Sec({ title, children, titleColor }) {
11
10
  return (react_1.default.createElement("div", { className: "mb-6" },
12
- react_1.default.createElement("div", { className: "text-[11px] font-bold text-tax-axis-teal-light uppercase tracking-widest mb-2.5 font-tax-axis-mono" }, title),
11
+ react_1.default.createElement("div", { className: "text-[11px] font-bold uppercase tracking-widest mb-2.5 font-tax-axis-mono", style: { color: titleColor || "#A1E5E6" } }, title),
13
12
  children));
14
13
  }
15
14
  const fmtK = (n) => `$${(n / 1000).toFixed(n % 1000 ? 1 : 0)}K`;
16
- function StrategyDetailPanel({ s, profile, computed, onClose }) {
17
- var _a, _b, _c, _d, _e, _f;
18
- const narr = data_1.STRATEGY_NARRATIVE[s.rank];
15
+ function positionStrengthLabel(positionStrength) {
16
+ if (!positionStrength)
17
+ return { label: "Position Under Review", color: "#9498B8", dots: 2 };
18
+ const p = positionStrength.toUpperCase();
19
+ if (p.includes("SUBSTANTIAL"))
20
+ return { label: "Substantial Authority · Low §6694 Risk", color: "#0F6E56", dots: 4 };
21
+ if (p.includes("REASONABLE"))
22
+ return { label: "Reasonable Basis · Elevated §6694 Risk", color: "#FB9A1D", dots: 3 };
23
+ if (p.includes("DISCLOSURE") || p.includes("NEEDS_DISCLOSURE"))
24
+ return { label: "Needs Disclosure · High §6694 Risk", color: "#EF4444", dots: 2 };
25
+ return { label: positionStrength, color: "#9498B8", dots: 2 };
26
+ }
27
+ /**
28
+ * Split engagement_recommendation into two parts:
29
+ * - savingsSection: sentences/paragraphs that contain dollar figures or formula references
30
+ * → shown as "HOW SAVINGS BREAK DOWN"
31
+ * - cpaSection: the remaining implementation/CPA-action paragraphs
32
+ * → shown as "CPA ENGAGEMENT NOTES"
33
+ *
34
+ * Strategy: split on double-newlines or sentence boundaries. Sentences with "$" or
35
+ * formulas go to savings; implementation/deadline/CPA sentences go to cpa.
36
+ */
37
+ function splitEngagementText(text) {
38
+ if (!text)
39
+ return { savingsSection: "", cpaSection: "" };
40
+ // Split into paragraphs first, then sentences within paragraphs
41
+ const rawParas = text.split(/\n{2,}/).map((p) => p.trim()).filter(Boolean);
42
+ const savingsParas = [];
43
+ const cpaParas = [];
44
+ for (const para of rawParas) {
45
+ const hasDollar = /\$[\d,]+/.test(para);
46
+ const hasFormula = /SAVINGS\s*=|CREDIT\s*=|DEDUCTION\s*=|ADDITIONAL_CONTRIBUTION/i.test(para);
47
+ const hasPercent = /\d+\.?\d*%/.test(para);
48
+ const hasCpaKeyword = /\bCPA\b|actuar|implement|deadline|establish|file|form\s+\d|verify|engage|model|recommend/i.test(para);
49
+ if ((hasDollar || hasFormula || hasPercent) && !hasCpaKeyword) {
50
+ savingsParas.push(para);
51
+ }
52
+ else if (savingsParas.length === 0) {
53
+ // First para with dollar amounts seeds savings section even if it has CPA keywords
54
+ if (hasDollar || hasFormula)
55
+ savingsParas.push(para);
56
+ else
57
+ cpaParas.push(para);
58
+ }
59
+ else {
60
+ cpaParas.push(para);
61
+ }
62
+ }
63
+ // If everything ended up in one bucket, put first para in savings, rest in cpa
64
+ if (!savingsParas.length && cpaParas.length) {
65
+ savingsParas.push(cpaParas.shift());
66
+ }
67
+ return {
68
+ savingsSection: savingsParas.join("\n\n"),
69
+ cpaSection: cpaParas.join("\n\n"),
70
+ };
71
+ }
72
+ function SourceDocRows({ docs, trace }) {
73
+ if (docs && docs.length > 0) {
74
+ return (react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { border: "1px solid rgba(36,131,132,0.12)" } },
75
+ react_1.default.createElement("div", { className: "grid px-3.5 py-2", style: { background: "#161938", gridTemplateColumns: "1fr auto" } },
76
+ react_1.default.createElement("span", { className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono" }, "Field \u00B7 Source"),
77
+ react_1.default.createElement("span", { className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono text-right" }, "Value")),
78
+ docs.map((ref, i) => (react_1.default.createElement("div", { key: i, className: "grid px-3.5 py-2.5 items-center gap-3", style: { gridTemplateColumns: "1fr auto", borderTop: "1px solid rgba(36,131,132,0.08)" } },
79
+ react_1.default.createElement("div", null,
80
+ react_1.default.createElement("div", { className: "text-xs text-tax-axis-text font-tax-axis-body" }, ref.field_label),
81
+ react_1.default.createElement("div", { className: "text-[10px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5" }, ref.source_hint)),
82
+ react_1.default.createElement("div", { className: "text-[13px] font-semibold text-tax-axis-teal-light font-tax-axis-mono text-right whitespace-nowrap" }, ref.value_display))))));
83
+ }
84
+ const traceSteps = trace !== null && trace !== void 0 ? trace : [];
85
+ if (!traceSteps.length) {
86
+ return react_1.default.createElement("p", { className: "text-xs text-tax-axis-text-2 italic" }, "Detailed source mapping not available for this strategy.");
87
+ }
88
+ return (react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { border: "1px solid rgba(36,131,132,0.12)" } },
89
+ react_1.default.createElement("div", { className: "grid grid-cols-2 px-3.5 py-2", style: { background: "#161938" } },
90
+ react_1.default.createElement("span", { className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono" }, "Step"),
91
+ react_1.default.createElement("span", { className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono text-right" }, "Result")),
92
+ traceSteps.map((t, i) => (react_1.default.createElement("div", { key: i, className: "grid grid-cols-2 px-3.5 py-2.5", style: { borderTop: "1px solid rgba(36,131,132,0.08)" } },
93
+ react_1.default.createElement("div", null,
94
+ react_1.default.createElement("div", { className: "text-xs text-tax-axis-text font-tax-axis-body" }, t.step),
95
+ react_1.default.createElement("div", { className: "text-[10px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5 break-all" }, t.formula)),
96
+ react_1.default.createElement("div", { className: "text-right" },
97
+ react_1.default.createElement("div", { className: "text-[13px] font-semibold text-tax-axis-teal-light font-tax-axis-mono" }, t.result),
98
+ t.src && react_1.default.createElement("div", { className: "text-[9px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5" }, t.src)))))));
99
+ }
100
+ function StrategyDetailPanel({ s, profile: _profile, computed, onClose }) {
101
+ var _a, _b;
19
102
  const c = computed === null || computed === void 0 ? void 0 : computed.get(s.rank);
20
103
  const lo = (_a = c === null || c === void 0 ? void 0 : c.lo) !== null && _a !== void 0 ? _a : s.lo;
21
104
  const hi = (_b = c === null || c === void 0 ? void 0 : c.hi) !== null && _b !== void 0 ? _b : s.hi;
22
- const sources = (_d = (_c = c === null || c === void 0 ? void 0 : c.sources) !== null && _c !== void 0 ? _c : s.sources) !== null && _d !== void 0 ? _d : [];
23
- const trace = (_f = (_e = c === null || c === void 0 ? void 0 : c.trace) !== null && _e !== void 0 ? _e : s.trace) !== null && _f !== void 0 ? _f : [];
24
- const whyText = narr ? narr.whyMatters(profile) : data_1.NARRATIVE_FALLBACK.whyMatters(s);
25
- const breakdownText = narr ? narr.breakdown(profile, c) : data_1.NARRATIVE_FALLBACK.breakdown(s, c);
26
- const specialistText = (narr === null || narr === void 0 ? void 0 : narr.whySpecialist) || data_1.NARRATIVE_FALLBACK.whySpecialist(s);
27
- const nextText = narr ? narr.nextSteps : data_1.NARRATIVE_FALLBACK.nextSteps(s);
105
+ const pos = positionStrengthLabel(s.positionStrength);
106
+ const { savingsSection, cpaSection } = splitEngagementText(s.abstract || "");
28
107
  return (react_1.default.createElement(react_1.default.Fragment, null,
29
108
  react_1.default.createElement("div", { onClick: onClose, className: "fixed inset-0 z-[200]", style: { background: "rgba(6,8,33,0.7)", backdropFilter: "blur(4px)" } }),
30
109
  react_1.default.createElement("div", { className: "fixed top-0 right-0 bottom-0 z-[201] flex flex-col", style: {
@@ -37,14 +116,14 @@ function StrategyDetailPanel({ s, profile, computed, onClose }) {
37
116
  react_1.default.createElement("div", { className: "px-6 py-5 flex-shrink-0", style: { borderBottom: "1px solid rgba(36,131,132,0.12)" } },
38
117
  react_1.default.createElement("div", { className: "flex justify-between items-start mb-3" },
39
118
  react_1.default.createElement("div", null,
40
- react_1.default.createElement("div", { className: "flex items-center gap-2 mb-1.5" },
119
+ react_1.default.createElement("div", { className: "flex items-center gap-2 mb-1.5 flex-wrap" },
41
120
  react_1.default.createElement("span", { className: "text-xl font-bold text-tax-axis-text font-tax-axis-head" }, s.name),
42
121
  react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-teal-light bg-tax-axis-teal-bg px-2 py-0.5 rounded" }, s.code)),
43
- react_1.default.createElement("div", { className: "flex gap-2" },
122
+ react_1.default.createElement("div", { className: "flex gap-2 flex-wrap" },
44
123
  react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, null, s.priority),
45
124
  react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: "neutral" }, s.timeline),
46
- s.cost && s.cost !== "$0" && (react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: "orange" }, s.cost)))),
47
- react_1.default.createElement("button", { onClick: onClose, className: "flex items-center justify-center w-8 h-8 rounded-lg", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
125
+ s.quickWin && react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: "orange" }, "\u26A1 Quick Win"))),
126
+ react_1.default.createElement("button", { onClick: onClose, className: "flex items-center justify-center w-8 h-8 rounded-lg flex-shrink-0", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
48
127
  react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
49
128
  react_1.default.createElement("path", { d: "M2.5 2.5l7 7M9.5 2.5l-7 7", stroke: "#9498B8", strokeWidth: "1.5", strokeLinecap: "round" })))),
50
129
  react_1.default.createElement("div", { className: "font-tax-axis-head", style: { fontSize: 34, fontWeight: 900, color: "#A1E5E6", letterSpacing: "-1.5px" } },
@@ -53,87 +132,40 @@ function StrategyDetailPanel({ s, profile, computed, onClose }) {
53
132
  fmtK(hi),
54
133
  react_1.default.createElement("span", { className: "text-[13px] text-tax-axis-text-3 font-normal font-tax-axis-body ml-2" }, "est. annual savings"))),
55
134
  react_1.default.createElement("div", { className: "flex-1 overflow-y-auto p-6" },
56
- s.warning && (react_1.default.createElement("div", { className: "p-3 rounded-lg mb-6 text-xs leading-relaxed", style: {
57
- background: "rgba(251,154,29,0.06)",
58
- border: "1px solid rgba(251,154,29,0.25)",
59
- color: "#FB9A1D",
60
- } },
135
+ s.warning && (react_1.default.createElement("div", { className: "p-3 rounded-lg mb-6 text-xs leading-relaxed", style: { background: "rgba(251,154,29,0.06)", border: "1px solid rgba(251,154,29,0.25)", color: "#FB9A1D" } },
61
136
  react_1.default.createElement("strong", null, "Flag: "),
62
137
  s.warning)),
63
- react_1.default.createElement("div", { className: "mb-6" },
64
- react_1.default.createElement("div", { className: "text-[11px] font-bold uppercase tracking-widest text-tax-axis-text-4 mb-2 font-tax-axis-mono" }, "WHY THIS MATTERS"),
65
- react_1.default.createElement("div", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body" }, whyText)),
66
- react_1.default.createElement("div", { className: "mb-6" },
67
- react_1.default.createElement("div", { className: "text-[11px] font-bold uppercase tracking-widest text-tax-axis-text-4 mb-2 font-tax-axis-mono" }, "HOW SAVINGS BREAK DOWN"),
68
- react_1.default.createElement("div", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body" }, breakdownText)),
69
- react_1.default.createElement("div", { className: "mb-6 pl-3.5 py-0.5", style: { borderLeft: "3px solid #FB9A1D" } },
70
- react_1.default.createElement("div", { className: "text-[11px] font-bold uppercase tracking-widest mb-2 font-tax-axis-mono", style: { color: "#FB9A1D" } }, "WHY YOU NEED A SPECIALIST"),
71
- react_1.default.createElement("div", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body" }, specialistText)),
72
- react_1.default.createElement("div", { className: "rounded-lg p-3 mb-6", style: { background: "rgba(36,131,132,0.06)", border: "1px solid rgba(36,131,132,0.2)" } },
73
- react_1.default.createElement("div", { className: "text-[11px] font-bold uppercase tracking-widest text-tax-axis-teal-light mb-1.5 font-tax-axis-mono" }, "WHAT WE'D DO NEXT"),
74
- react_1.default.createElement("div", { className: "text-[13px] text-tax-axis-text leading-[1.7] font-tax-axis-body" }, typeof nextText === "string" ? nextText : "Provide documents so we can calculate exact savings.")),
75
- react_1.default.createElement(Sec, { title: "Summary" },
76
- react_1.default.createElement("p", { className: "text-sm text-tax-axis-text leading-[1.8] font-tax-axis-body" }, s.abstract)),
77
- react_1.default.createElement(Sec, { title: "Plain Language" },
78
- react_1.default.createElement("div", { className: "p-3.5 rounded-[10px]", style: { background: "rgba(36,131,132,0.06)", border: "1px solid rgba(36,131,132,0.2)" } },
79
- react_1.default.createElement("p", { className: "text-sm text-tax-axis-teal-light leading-[1.7] font-tax-axis-body italic" },
80
- "\u201C",
81
- s.clientBrief,
82
- "\u201D"))),
83
- react_1.default.createElement(Sec, { title: "Source Documents" },
84
- react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { border: "1px solid rgba(36,131,132,0.12)" } },
85
- react_1.default.createElement("div", { className: "grid grid-cols-[1.2fr_1fr_.8fr_.8fr] px-3.5 py-2.5", style: { background: "#161938" } }, ["Field", "Document", "Line", "Value"].map((h) => (react_1.default.createElement("span", { key: h, className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono" }, h)))),
86
- sources.map((src, i) => (react_1.default.createElement("div", { key: i, className: "grid grid-cols-[1.2fr_1fr_.8fr_.8fr] px-3.5 py-2.5", style: { borderTop: "1px solid rgba(36,131,132,0.12)" } },
87
- react_1.default.createElement("span", { className: "text-xs text-tax-axis-text" }, src.field),
88
- react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, src.doc),
89
- react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, src.line),
90
- react_1.default.createElement("span", { className: "text-[13px] font-semibold text-tax-axis-teal-light font-tax-axis-mono" }, src.value)))))),
91
- react_1.default.createElement(Sec, { title: "Calculation Trace" },
92
- react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { border: "1px solid rgba(36,131,132,0.12)" } },
93
- trace.map((t, i) => (react_1.default.createElement("div", { key: i, className: "p-3 flex gap-3 items-start", style: { borderTop: i ? "1px solid rgba(36,131,132,0.12)" : "none" } },
94
- react_1.default.createElement("span", { className: "text-[11px] font-bold text-tax-axis-teal font-tax-axis-mono w-5 flex-shrink-0" }, t.n),
95
- react_1.default.createElement("div", { className: "flex-1" },
96
- react_1.default.createElement("div", { className: "text-[13px] font-medium text-tax-axis-text font-tax-axis-body mb-0.5" }, t.step),
97
- react_1.default.createElement("div", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, t.formula)),
98
- react_1.default.createElement("div", { className: "text-right flex-shrink-0" },
99
- react_1.default.createElement("div", { className: "text-[13px] font-bold text-tax-axis-teal-light font-tax-axis-mono" }, t.result),
100
- react_1.default.createElement("div", { className: "text-[9px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5" }, t.src))))),
101
- react_1.default.createElement("div", { className: "p-3.5", style: { borderTop: "1px solid rgba(36,131,132,0.12)", background: "#161938" } },
102
- react_1.default.createElement("div", { className: "text-[10px] font-bold text-tax-axis-teal-light uppercase tracking-widest mb-2 font-tax-axis-mono" }, "Derivation"),
103
- react_1.default.createElement("div", { className: "flex items-center gap-2 flex-wrap" }, trace.map((t, i) => (react_1.default.createElement("span", { key: i, className: "flex items-center gap-1.5" },
104
- react_1.default.createElement("span", { className: "text-xs font-tax-axis-mono text-tax-axis-text px-2 py-0.5 rounded", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } }, t.result),
105
- i < trace.length - 1 && (react_1.default.createElement("span", { className: "text-[11px] text-tax-axis-text-3 font-tax-axis-mono" }, "\u2192")))))),
106
- trace.length > 1 && (react_1.default.createElement("div", { className: "mt-2 text-xs font-tax-axis-mono p-2 rounded-md leading-relaxed", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
107
- react_1.default.createElement("span", { className: "text-tax-axis-text-2" }, "Result: "),
108
- react_1.default.createElement("span", { className: "font-semibold text-tax-axis-teal-light" }, trace[trace.length - 1].result),
109
- react_1.default.createElement("span", { className: "text-tax-axis-text-2" }, " via "),
110
- react_1.default.createElement("span", { className: "text-tax-axis-text" }, trace[trace.length - 1].formula)))))),
111
- react_1.default.createElement(Sec, { title: "IRS Authority" },
138
+ s.clientBrief && (react_1.default.createElement(Sec, { title: "Why This Matters" },
139
+ react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body" }, s.clientBrief))),
140
+ savingsSection && (react_1.default.createElement(Sec, { title: "How Savings Break Down" },
141
+ react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body whitespace-pre-line" }, savingsSection))),
142
+ s.specialistNote && (react_1.default.createElement("div", { className: "mb-6 pl-3.5 py-1", style: { borderLeft: "3px solid #FB9A1D" } },
143
+ react_1.default.createElement("div", { className: "text-[11px] font-bold uppercase tracking-widest mb-2 font-tax-axis-mono", style: { color: "#FB9A1D" } }, "Why You Need a Specialist"),
144
+ react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body" }, s.specialistNote))),
145
+ react_1.default.createElement(Sec, { title: "Data Used in This Analysis" },
146
+ react_1.default.createElement(SourceDocRows, { docs: s.sourceDocuments, trace: s.trace })),
147
+ cpaSection && (react_1.default.createElement(Sec, { title: "CPA Engagement Notes", titleColor: "#9498B8" },
148
+ react_1.default.createElement("div", { className: "rounded-[10px] p-3.5", style: { background: "rgba(14,17,50,0.6)", border: "1px solid rgba(36,131,132,0.10)" } },
149
+ react_1.default.createElement("p", { className: "text-[12px] text-tax-axis-text-3 leading-[1.75] font-tax-axis-body whitespace-pre-line" }, cpaSection)))),
150
+ react_1.default.createElement(Sec, { title: "IRS Authority", titleColor: "#9498B8" },
112
151
  react_1.default.createElement("div", { className: "p-3.5 rounded-[10px] mb-3", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
113
- react_1.default.createElement("div", { className: "text-[13px] font-tax-axis-mono text-tax-axis-text mb-1" }, s.authority),
114
- react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2" },
152
+ react_1.default.createElement("div", { className: "text-[13px] font-tax-axis-mono text-tax-axis-text mb-1" }, s.authority || "See engagement notes"),
153
+ s.forms && (react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2" },
115
154
  "Forms: ",
116
- react_1.default.createElement("span", { className: "font-tax-axis-mono text-tax-axis-text" }, s.forms))),
155
+ react_1.default.createElement("span", { className: "font-tax-axis-mono text-tax-axis-text" }, s.forms)))),
117
156
  react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { background: "rgba(36,131,132,0.06)", border: "1px solid rgba(36,131,132,0.2)" } },
118
157
  react_1.default.createElement("div", { className: "p-3 flex gap-3 items-center", style: { borderBottom: "1px solid rgba(36,131,132,0.15)" } },
119
- react_1.default.createElement("div", { className: "flex gap-[3px]" }, [1, 2, 3, 4, 5].map((i) => (react_1.default.createElement("div", { key: i, className: "w-2 h-2 rounded-sm", style: { background: i <= 4 ? "#248384" : "rgba(36,131,132,0.2)" } })))),
120
- react_1.default.createElement("span", { className: "text-[13px] font-semibold text-tax-axis-teal-light font-tax-axis-head" }, "Substantial Authority \u00B7 Low \u00A76694 Risk")),
158
+ react_1.default.createElement("div", { className: "flex gap-[3px]" }, [1, 2, 3, 4, 5].map((i) => (react_1.default.createElement("div", { key: i, className: "w-2 h-2 rounded-sm", style: { background: i <= pos.dots ? pos.color : "rgba(36,131,132,0.2)" } })))),
159
+ react_1.default.createElement("span", { className: "text-[13px] font-semibold font-tax-axis-head", style: { color: pos.color } }, pos.label)),
121
160
  react_1.default.createElement("div", { className: "p-3" },
122
- react_1.default.createElement("p", { className: "text-xs text-tax-axis-text leading-[1.7] font-tax-axis-body mb-2" }, "IRC \u00A76694 imposes penalties on preparers who sign off on positions that lack sufficient legal support. There are two tiers:"),
123
- react_1.default.createElement("div", { className: "grid gap-1.5 mb-2.5" },
124
- react_1.default.createElement("div", { className: "p-2 rounded-md", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
125
- react_1.default.createElement("div", { className: "text-[11px] font-semibold text-tax-axis-text font-tax-axis-head mb-0.5" }, "Tier 1 \u2014 Unreasonable Position"),
126
- react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2 leading-relaxed font-tax-axis-body" }, "If a position lacks \u201Csubstantial authority\u201D (~40% chance of being sustained), the preparer faces the greater of $1,000 or 50% of the fee earned from that return.")),
127
- react_1.default.createElement("div", { className: "p-2 rounded-md", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
128
- react_1.default.createElement("div", { className: "text-[11px] font-semibold text-tax-axis-text font-tax-axis-head mb-0.5" }, "Tier 2 \u2014 Willful or Reckless Conduct"),
129
- react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2 leading-relaxed font-tax-axis-body" }, "If the preparer knowingly disregards rules or regulations, the penalty is the greater of $5,000 or 75% of the fee earned."))),
130
- react_1.default.createElement("div", { className: "p-2 rounded-md flex gap-2 items-start", style: { background: "rgba(15,110,86,0.06)", border: "1px solid rgba(15,110,86,0.15)" } },
131
- react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", className: "flex-shrink-0 mt-0.5" },
132
- react_1.default.createElement("path", { d: "M2.5 7l3.5 3.5 5.5-6", stroke: "#0F6E56", strokeWidth: "1.5", strokeLinecap: "round" })),
133
- react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text leading-relaxed font-tax-axis-body" },
134
- react_1.default.createElement("strong", { style: { color: "#0F6E56" } }, "This strategy holds Substantial Authority"),
135
- " \u2014 established IRS guidance, published revenue rulings, or settled case law support this position. Signing off on this carries low preparer penalty exposure under \u00A76694(a).")))))),
161
+ react_1.default.createElement("p", { className: "text-xs text-tax-axis-text leading-[1.7] font-tax-axis-body" },
162
+ "IRC \u00A76694 imposes penalties on preparers who sign off on positions that lack sufficient legal support.",
163
+ pos.dots >= 4
164
+ ? " This strategy holds Substantial Authority established IRS guidance supports this position. Low preparer penalty exposure under §6694(a)."
165
+ : pos.dots === 3
166
+ ? " This strategy rests on Reasonable Basis. CPA should document the position before filing and consider disclosure on Form 8275."
167
+ : " This strategy requires preparer disclosure. Consult IRS guidance before taking this position."))))),
136
168
  react_1.default.createElement("div", { className: "px-6 py-4 flex-shrink-0", style: { borderTop: "1px solid rgba(36,131,132,0.12)", background: "#0E1132" } },
137
- react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-3 mb-2" }, "Recommended action:"),
138
- react_1.default.createElement("div", { className: "text-sm font-medium text-tax-axis-text" }, s.action)))));
169
+ react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-3 uppercase tracking-widest font-tax-axis-mono mb-2" }, "What We'd Do Next"),
170
+ react_1.default.createElement("div", { className: "text-sm font-medium text-tax-axis-text leading-relaxed" }, s.action || "Work with your CPA to implement this strategy.")))));
139
171
  }
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { ClientProfile, TaxAxisScreenProps } from "../../lib/types";
2
+ import type { ClientProfile, TaxAxisScreenProps, ExtractionDocument } from "../../lib/types";
3
3
  export interface LlmStrategy {
4
4
  strategyType: string;
5
5
  applicable: boolean;
@@ -57,6 +57,7 @@ export interface LlmResult {
57
57
  export interface TaxAxisDashboardProps extends TaxAxisScreenProps {
58
58
  profile: ClientProfile;
59
59
  llmResult?: LlmResult | null;
60
+ parsedDocuments?: ExtractionDocument[];
60
61
  onDownloadClient: () => void;
61
62
  onDownloadPreparer: () => void;
62
63
  onPresent: () => void;
@@ -65,4 +66,4 @@ export interface TaxAxisDashboardProps extends TaxAxisScreenProps {
65
66
  onReviewData?: () => void;
66
67
  onUploadMore?: () => void;
67
68
  }
68
- export declare function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext, }: TaxAxisDashboardProps): React.JSX.Element;
69
+ export declare function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext, }: TaxAxisDashboardProps): React.JSX.Element;
@@ -145,9 +145,23 @@ const BUCKETS = [
145
145
  { key: "30d", label: "Within 30 Days", desc: "Documentation or payroll changes" },
146
146
  { key: "90d", label: "Within 90 Days", desc: "Structural changes — new accounts or plan setup" },
147
147
  ];
148
- function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext = "expert", }) {
149
- var _a, _b;
148
+ function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext = "expert", }) {
149
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
150
150
  const hasLlm = !!((_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.strategies) === null || _a === void 0 ? void 0 : _a.length);
151
+ // All live fields from rawOutput — nothing hardcoded
152
+ const rawOutput = (_c = (_b = llmResult === null || llmResult === void 0 ? void 0 : llmResult.rawOutput) !== null && _b !== void 0 ? _b : llmResult === null || llmResult === void 0 ? void 0 : llmResult.engineOutput) !== null && _c !== void 0 ? _c : null;
153
+ const businessProfile = (_d = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.business_profile) !== null && _d !== void 0 ? _d : null;
154
+ const dataQualityFlags = (_e = businessProfile === null || businessProfile === void 0 ? void 0 : businessProfile.data_quality_flags) !== null && _e !== void 0 ? _e : [];
155
+ const riskDisclosures = (_f = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.risk_disclosures) !== null && _f !== void 0 ? _f : [];
156
+ const nexusFlags = (_g = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.nexus_flags) !== null && _g !== void 0 ? _g : [];
157
+ const engagementRecs = (_j = (_h = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.cpa_workflow) === null || _h === void 0 ? void 0 : _h.engagement_recommendations) !== null && _j !== void 0 ? _j : [];
158
+ const excludedStrategies = (_l = (_k = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.eligibility_screening) === null || _k === void 0 ? void 0 : _k.excluded_strategies) !== null && _l !== void 0 ? _l : [];
159
+ const clientSummaryOpening = (_o = (_m = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.client_summary) === null || _m === void 0 ? void 0 : _m.opening) !== null && _o !== void 0 ? _o : "";
160
+ const clientSummaryClosing = (_q = (_p = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.client_summary) === null || _p === void 0 ? void 0 : _p.closing) !== null && _q !== void 0 ? _q : "";
161
+ const dataQualityNote = (_s = (_r = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.client_summary) === null || _r === void 0 ? void 0 : _r.data_quality_note) !== null && _s !== void 0 ? _s : "";
162
+ const interactionWarning = (_u = (_t = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.client_summary) === null || _t === void 0 ? void 0 : _t.interaction_warning) !== null && _u !== void 0 ? _u : null;
163
+ // Extracted documents: live from session if provided, otherwise empty (no mock fallback)
164
+ const extractionDocs = parsedDocuments !== null && parsedDocuments !== void 0 ? parsedDocuments : [];
151
165
  // ─── Derived data ──────────────────────────────────────────────
152
166
  const llmStrategies = (0, react_1.useMemo)(() => (hasLlm ? mapLlmToStrategies(llmResult) : []), [hasLlm, llmResult]);
153
167
  const llmComputed = (0, react_1.useMemo)(() => (hasLlm ? buildLlmComputed(llmStrategies) : new Map()), [hasLlm, llmStrategies]);
@@ -163,9 +177,13 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
163
177
  // When LLM result is present, data is implicitly confirmed — skip the gate
164
178
  const [dataConfirmed, setDataConfirmed] = (0, react_1.useState)(hasLlm);
165
179
  const [reviewStatus, setReviewStatus] = (0, react_1.useState)({
166
- unreviewed: data_1.EXTRACTED_DATA.reduce((a, d) => a + d.flagCount, 0),
180
+ unreviewed: extractionDocs.reduce((a, d) => a + d.flagCount, 0),
167
181
  edits: 0,
168
182
  });
183
+ // Keep review count in sync when live docs arrive after initial render
184
+ (0, react_1.useEffect)(() => {
185
+ setReviewStatus((prev) => (Object.assign(Object.assign({}, prev), { unreviewed: extractionDocs.reduce((a, d) => a + d.flagCount, 0) })));
186
+ }, [extractionDocs]);
169
187
  // Restore confirmed state on mount — flag persists until session reset
170
188
  (0, react_1.useEffect)(() => {
171
189
  if (typeof window !== "undefined" && sessionStorage.getItem("taxAxisDataConfirmed") === "true") {
@@ -216,19 +234,28 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
216
234
  llmResult.meta.parsedDocumentCount,
217
235
  " documents parsed",
218
236
  " · ",
219
- ((_b = llmResult.meta.detectedDocumentTypes) === null || _b === void 0 ? void 0 : _b.length) || 0,
237
+ ((_v = llmResult.meta.detectedDocumentTypes) === null || _v === void 0 ? void 0 : _v.length) || 0,
220
238
  " document types detected"),
221
239
  react_1.default.createElement("span", { className: "text-tax-axis-text-4" }, (() => {
222
240
  var _a, _b;
223
241
  const tokens = (_b = (_a = llmResult.meta.totalTokens) !== null && _a !== void 0 ? _a : llmResult.meta.tokenCount) !== null && _b !== void 0 ? _b : 0;
224
242
  return tokens > 0 ? `${tokens} tokens` : "";
225
243
  })()))),
226
- react_1.default.createElement(DashboardSummary_1.DashboardSummary, { profile: profile, dashEligible: dashEligible, computed: computed, dataConfirmed: dataConfirmed, reviewUnreviewed: reviewStatus.unreviewed }),
244
+ react_1.default.createElement(DashboardSummary_1.DashboardSummary, { profile: profile, dashEligible: dashEligible, computed: computed, dataConfirmed: dataConfirmed, reviewUnreviewed: reviewStatus.unreviewed, liveSavingsMin: hasLlm ? llmResult.summary.estimatedSavingsMin : undefined, liveSavingsMax: hasLlm ? llmResult.summary.estimatedSavingsMax : undefined, liveStrategyCount: hasLlm ? llmResult.summary.applicableCount : undefined, confidenceTier: businessProfile === null || businessProfile === void 0 ? void 0 : businessProfile.confidence_tier, dataYears: businessProfile === null || businessProfile === void 0 ? void 0 : businessProfile.data_years }),
227
245
  react_1.default.createElement(DashboardTopBar_1.DashboardTopBar, { topTab: topTab, setTopTab: setTopTab, dataConfirmed: dataConfirmed, reviewUnreviewed: reviewStatus.unreviewed }),
228
246
  topTab === "extraction" && (react_1.default.createElement("div", null,
247
+ dataQualityFlags.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.2)", padding: "16px 20px" } },
248
+ react_1.default.createElement("div", { className: "text-[11px] font-bold text-white uppercase tracking-widest font-tax-axis-mono mb-2.5 flex items-center gap-2" },
249
+ react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
250
+ react_1.default.createElement("path", { d: "M6 1.5l5 9H1L6 1.5z", stroke: "#FB9A1D", strokeWidth: "1.2", fill: "none" }),
251
+ react_1.default.createElement("path", { d: "M6 5v2.5M6 9h.005", stroke: "#FB9A1D", strokeWidth: "1.2", strokeLinecap: "round" })),
252
+ "Data Quality Flags"),
253
+ dataQualityFlags.map((flag, i) => (react_1.default.createElement("div", { key: i, className: "text-[11px] text-tax-axis-text-2 font-tax-axis-body py-1.5", style: { borderTop: i > 0 ? "1px solid rgba(251,154,29,0.1)" : "none" } }, flag))))),
229
254
  react_1.default.createElement("div", { className: "rounded-[14px] mb-4", style: { background: "#0E1132", border: "1px solid rgba(36,131,132,0.12)", padding: "20px 24px" } },
230
255
  react_1.default.createElement("div", { className: "text-[13px] font-bold text-white uppercase tracking-widest font-tax-axis-head mb-3" }, "Document Extraction Summary"),
231
- data_1.EXTRACTED_DATA.map((doc) => (react_1.default.createElement("div", { key: doc.docId, className: "flex items-center justify-between py-2.5", style: { borderTop: "1px solid rgba(36,131,132,0.08)" } },
256
+ extractionDocs.length === 0 ? (react_1.default.createElement("div", { className: "text-[12px] text-tax-axis-text-3 font-tax-axis-body py-2" }, hasLlm
257
+ ? "Parsed document data is loading..."
258
+ : "No documents have been parsed yet.")) : (extractionDocs.map((doc) => (react_1.default.createElement("div", { key: doc.docId, className: "flex items-center justify-between py-2.5", style: { borderTop: "1px solid rgba(36,131,132,0.08)" } },
232
259
  react_1.default.createElement("div", { className: "flex items-center gap-3" },
233
260
  react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-teal-light bg-tax-axis-teal-bg px-2 py-0.5 rounded" }, doc.code),
234
261
  react_1.default.createElement("span", { className: "text-[13px] text-tax-axis-text font-tax-axis-body" }, doc.docName)),
@@ -236,9 +263,8 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
236
263
  react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-3" },
237
264
  doc.fields.length,
238
265
  " fields"),
239
- doc.flagCount > 0 && (react_1.default.createElement("span", { className: "text-[10px] font-semibold font-tax-axis-mono rounded-full min-w-[18px] text-center px-1.5 py-0.5", style: { color: "#FB9A1D", background: "rgba(251,154,29,0.06)" } }, doc.flagCount)),
240
- doc.flagCount === 0 && (react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
241
- react_1.default.createElement("path", { d: "M2.5 6l3 3 4.5-5", stroke: "#0F6E56", strokeWidth: "1.5", strokeLinecap: "round" })))))))),
266
+ doc.flagCount > 0 ? (react_1.default.createElement("span", { className: "text-[10px] font-semibold font-tax-axis-mono rounded-full min-w-[18px] text-center px-1.5 py-0.5", style: { color: "#FB9A1D", background: "rgba(251,154,29,0.06)" } }, doc.flagCount)) : (react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
267
+ react_1.default.createElement("path", { d: "M2.5 6l3 3 4.5-5", stroke: "#0F6E56", strokeWidth: "1.5", strokeLinecap: "round" }))))))))),
242
268
  !dataConfirmed ? (react_1.default.createElement("div", { className: "rounded-[14px]", style: {
243
269
  background: "linear-gradient(135deg, rgba(36,131,132,0.12), rgba(36,131,132,0.06))",
244
270
  border: "1px solid rgba(36,131,132,0.3)",
@@ -421,17 +447,32 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
421
447
  react_1.default.createElement("div", { className: "flex items-center gap-2.5" },
422
448
  react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, a.savings),
423
449
  react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: a.priority === "MEDIUM" ? "orange" : "neutral", size: "xs" }, a.priority))))))),
424
- react_1.default.createElement("div", { className: "rounded-[10px] mb-4 text-xs text-tax-axis-text leading-[1.7] font-tax-axis-body", style: {
425
- padding: "14px 18px",
426
- background: "#0E1132",
427
- border: "1px solid rgba(36,131,132,0.12)",
428
- } },
429
- react_1.default.createElement("strong", null, "\u00A76694 Preparer Compliance \u2014 "),
430
- "All HIGH priority strategies hold Substantial Authority (established IRS guidance supporting the position). No elevated preparer penalty exposure for positions taken on these strategies. OBBBA strategies default to Reasonable Basis pending IRS guidance \u2014 CPA verification required before filing."),
450
+ engagementRecs.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4 overflow-hidden", style: { background: "#0E1132", border: "1px solid rgba(36,131,132,0.12)" } },
451
+ react_1.default.createElement("div", { className: "px-5 py-3.5", style: { borderBottom: "1px solid rgba(36,131,132,0.12)" } },
452
+ react_1.default.createElement("span", { className: "text-[13px] font-bold text-white uppercase tracking-widest font-tax-axis-head" }, "CPA Engagement Notes")),
453
+ engagementRecs.map((rec, i) => (react_1.default.createElement("div", { key: i, className: "px-5 py-3.5 text-[12px] text-tax-axis-text leading-[1.7] font-tax-axis-body", style: { borderTop: i > 0 ? "1px solid rgba(36,131,132,0.08)" : "none" } }, rec))))),
454
+ nexusFlags.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4", style: { background: "#0E1132", border: "1px solid rgba(36,131,132,0.12)", padding: "16px 20px" } },
455
+ react_1.default.createElement("div", { className: "text-[11px] font-bold text-white uppercase tracking-widest font-tax-axis-mono mb-2" }, "State Nexus"),
456
+ nexusFlags.map((f, i) => (react_1.default.createElement("div", { key: i, className: "text-[12px] text-tax-axis-text-2 font-tax-axis-body py-1.5", style: { borderTop: i > 0 ? "1px solid rgba(36,131,132,0.08)" : "none" } },
457
+ react_1.default.createElement("span", { className: "font-semibold text-tax-axis-teal-light mr-2" }, f.state),
458
+ f.flag_text))))),
459
+ riskDisclosures.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.15)", padding: "16px 20px" } },
460
+ react_1.default.createElement("div", { className: "text-[11px] font-bold text-white uppercase tracking-widest font-tax-axis-mono mb-2.5" }, "Risk Disclosures"),
461
+ riskDisclosures.map((r, i) => (react_1.default.createElement("div", { key: i, className: "text-[11px] text-tax-axis-text-2 font-tax-axis-body py-1.5", style: { borderTop: i > 0 ? "1px solid rgba(251,154,29,0.08)" : "none" } }, r))))),
462
+ excludedStrategies.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4 overflow-hidden", style: { background: "#0E1132", border: "1px solid rgba(148,152,184,0.15)" } },
463
+ react_1.default.createElement("div", { className: "px-5 py-3.5", style: { borderBottom: "1px solid rgba(148,152,184,0.1)" } },
464
+ react_1.default.createElement("span", { className: "text-[13px] font-bold text-white uppercase tracking-widest font-tax-axis-head" },
465
+ excludedStrategies.length,
466
+ " Strategies Not Applicable")),
467
+ excludedStrategies.map((ex, i) => (react_1.default.createElement("div", { key: i, className: "px-5 py-2.5 flex items-start gap-3", style: { borderTop: i > 0 ? "1px solid rgba(148,152,184,0.08)" : "none" } },
468
+ react_1.default.createElement("span", { className: "text-[10px] font-semibold font-tax-axis-mono text-tax-axis-text-3 bg-tax-axis-surface px-2 py-0.5 rounded flex-shrink-0 mt-0.5" }, ex.strategy_id),
469
+ react_1.default.createElement("div", { className: "flex-1" },
470
+ react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2 font-tax-axis-body" }, ex.reason),
471
+ ex.irs_cite && (react_1.default.createElement("div", { className: "text-[10px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5" }, ex.irs_cite)))))))),
431
472
  react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onDownloadPreparer, className: "w-full" }, "Download Full Preparer Report"))) : (
432
473
  /* ═══ CLIENT SUMMARY — Timeline View ═══ */
433
474
  react_1.default.createElement("div", null,
434
- react_1.default.createElement("p", { className: "text-sm text-tax-axis-text leading-[1.7] mb-6 font-tax-axis-body" },
475
+ clientSummaryOpening ? (react_1.default.createElement("div", { className: "rounded-[10px] mb-5 text-[12px] text-tax-axis-text leading-[1.7] font-tax-axis-body", style: { background: "rgba(36,131,132,0.04)", border: "1px solid rgba(36,131,132,0.1)", padding: "14px 16px" } }, clientSummaryOpening)) : (react_1.default.createElement("p", { className: "text-sm text-tax-axis-text leading-[1.7] mb-6 font-tax-axis-body" },
435
476
  profile.bizName || "Client",
436
477
  ", here's your action plan organized by urgency.",
437
478
  " ",
@@ -439,7 +480,13 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
439
480
  dashEligible.length,
440
481
  " strategies"),
441
482
  " ",
442
- "identified."),
483
+ "identified.")),
484
+ dataQualityNote && (react_1.default.createElement("div", { className: "rounded-[10px] mb-5 text-[11px] text-tax-axis-text-2 font-tax-axis-body flex items-start gap-2", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.15)", padding: "10px 14px" } },
485
+ react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", className: "flex-shrink-0 mt-0.5" },
486
+ react_1.default.createElement("circle", { cx: "6", cy: "6", r: "5", stroke: "#FB9A1D", strokeWidth: "1" }),
487
+ react_1.default.createElement("path", { d: "M6 4v2.5M6 8h.005", stroke: "#FB9A1D", strokeWidth: "1", strokeLinecap: "round" })),
488
+ dataQualityNote)),
489
+ interactionWarning && (react_1.default.createElement("div", { className: "rounded-[10px] mb-5 text-[11px] text-tax-axis-text-2 font-tax-axis-body", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.15)", padding: "10px 14px" } }, interactionWarning)),
443
490
  BUCKETS.map(({ key, label, desc }) => {
444
491
  const items = dashEligible.filter((s) => s.timelineBucket === key);
445
492
  if (!items.length)
@@ -488,7 +535,8 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
488
535
  s.cost && s.cost !== "$0" && (react_1.default.createElement("span", { className: "text-[11px] font-semibold font-tax-axis-mono", style: { color: "#FB9A1D" } }, s.cost)))));
489
536
  })));
490
537
  }),
491
- react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onDownloadClient, className: "w-full mt-1.5" }, "Download Client Summary"))),
538
+ react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onDownloadClient, className: "w-full mt-1.5" }, "Download Client Summary"),
539
+ clientSummaryClosing && (react_1.default.createElement("div", { className: "mt-4 text-[11px] text-tax-axis-text-3 leading-[1.65] font-tax-axis-body", style: { borderTop: "1px solid rgba(36,131,132,0.08)", paddingTop: 14 } }, clientSummaryClosing)))),
492
540
  react_1.default.createElement(DashboardActions_1.DashboardActions, { profile: profile, dashEligible: dashEligible, computed: computed, onDownloadPreparer: onDownloadPreparer, onPresent: onPresent, onSend: onSend, onReset: onReset }))),
493
541
  enrichedSelected && (react_1.default.createElement(StrategyDetailPanel_1.StrategyDetailPanel, { s: enrichedSelected, profile: profile, computed: computed, onClose: () => setSelected(null) }))));
494
542
  }
@@ -16,12 +16,14 @@ export interface TaxAxisDocumentsProps extends TaxAxisScreenProps {
16
16
  }>;
17
17
  onDeleteDocument?: (documentId: string) => Promise<void>;
18
18
  fetchUploadedDocuments?: () => Promise<Array<{
19
+ documentId?: string;
19
20
  fileName: string;
20
21
  status: string;
21
22
  documentType?: string | null;
22
23
  parseError?: string | null;
23
24
  updatedAt?: string | null;
24
25
  parsedData?: Record<string, unknown> | null;
26
+ reviewedData?: Record<string, unknown> | null;
25
27
  }>>;
26
28
  parsedFieldCounts?: Record<string, number>;
27
29
  jobId?: string;