import { useState } from "react";
const C = {
navy: "#0D1B2A",
navy2: "#0A1520",
gold: "#B8945F",
goldL: "#C9A96E",
cream: "#FAF8F4",
tx: "#2C3038",
tm: "#6B7280",
tf: "#9CA3AF",
bd: "#E8E3DB",
green: "#27AE60",
lgreen: "#D5F5E3",
red: "#A93226",
lred: "#FADBD8",
amber: "#B7770D",
lamber: "#FDEBD0",
teal: "#0E6655",
lteal: "#D1F2EB",
lnavy: "#D6EAF8",
lgrey: "#F4F5F7",
mgrey: "#CDD0D4",
};
const styles = {
wrap: { fontFamily: "'DM Sans', system-ui, sans-serif", background: C.cream, minHeight: "100vh", fontSize: 13 },
topbar: { background: C.navy, padding: "0 20px", display: "flex", alignItems: "center", gap: 16, height: 48, borderBottom: `2px solid ${C.gold}` },
topbrand: { color: C.gold, fontWeight: 700, fontSize: 11, letterSpacing: 4, textTransform: "uppercase" },
topsep: { color: "rgba(255,255,255,0.2)", fontSize: 16 },
topscreen: { color: "rgba(255,255,255,0.6)", fontSize: 11 },
sidebar: { width: 200, background: C.navy2, minHeight: "calc(100vh - 48px)", padding: "16px 0", flexShrink: 0 },
navitem: (active) => ({ padding: "8px 16px", cursor: "pointer", fontSize: 11, fontWeight: active ? 700 : 400,
color: active ? C.gold : "rgba(255,255,255,0.5)", background: active ? "rgba(184,148,95,0.12)" : "transparent",
borderLeft: active ? `3px solid ${C.gold}` : "3px solid transparent",
display: "flex", alignItems: "center", gap: 8, transition: "all 0.15s" }),
navcat: { padding: "16px 16px 6px", fontSize: 9, color: "rgba(255,255,255,0.25)", letterSpacing: 3, textTransform: "uppercase", fontWeight: 700 },
content: { flex: 1, padding: 24, overflow: "auto" },
card: { background: "white", borderRadius: 6, border: `1px solid ${C.bd}`, padding: 20, marginBottom: 16 },
cardTitle: { fontWeight: 700, color: C.navy, fontSize: 13, marginBottom: 4 },
cardSub: { color: C.tm, fontSize: 11, marginBottom: 16 },
label: { fontSize: 10, fontWeight: 700, color: C.tm, textTransform: "uppercase", letterSpacing: 1, marginBottom: 4, display: "block" },
input: { width: "100%", border: `1px solid ${C.bd}`, borderRadius: 4, padding: "8px 10px", fontSize: 12, color: C.tx, outline: "none", boxSizing: "border-box" },
btn: (v="primary") => ({ padding: "8px 16px", borderRadius: 4, border: "none", cursor: "pointer", fontWeight: 700, fontSize: 11,
background: v==="primary" ? C.gold : v==="danger" ? C.red : v==="ghost" ? "transparent" : C.lgrey,
color: v==="primary" ? "white" : v==="danger" ? "white" : v==="ghost" ? C.tm : C.navy,
border: v==="ghost" ? `1px solid ${C.bd}` : "none" }),
badge: (c="grey") => ({ display: "inline-block", padding: "2px 8px", borderRadius: 3, fontSize: 10, fontWeight: 700,
background: c==="green" ? C.lgreen : c==="red" ? C.lred : c==="amber" ? C.lamber : c==="navy" ? C.lnavy : c==="teal" ? C.lteal : C.lgrey,
color: c==="green" ? C.green : c==="red" ? C.red : c==="amber" ? C.amber : c==="navy" ? C.navy : c==="teal" ? C.teal : C.tm }),
grade: (g) => ({ display: "inline-flex", alignItems: "center", justifyContent: "center", width: 28, height: 28, borderRadius: 4, fontWeight: 900, fontSize: 14,
background: g==="A" ? C.lgreen : g==="B" ? C.lnavy : g==="C" ? C.lamber : g==="D" ? C.lred : C.lgrey,
color: g==="A" ? C.green : g==="B" ? C.navy : g==="C" ? C.amber : g==="D" ? C.red : C.tm }),
table: { width: "100%", borderCollapse: "collapse", fontSize: 11 },
th: { background: C.navy, color: C.goldL, padding: "6px 10px", textAlign: "left", fontSize: 10, fontWeight: 700, letterSpacing: 0.5 },
td: { padding: "7px 10px", borderBottom: `1px solid ${C.bd}`, verticalAlign: "top" },
row: (i) => ({ background: i%2===0 ? "white" : C.lgrey }),
sla: (pct) => ({ height: 4, borderRadius: 2, background: pct > 75 ? C.red : pct > 50 ? C.amber : C.green, width: `${pct}%`, transition: "width 0.3s" }),
slaTrack: { height: 4, borderRadius: 2, background: C.lgrey, width: "100%", overflow: "hidden", marginTop: 2 },
};
// ── SHARED COMPONENTS ────────────────────────────────────────────────────────
const GradeBlock = ({ block, grade, label }) => (
);
const Tag = ({ children, color }) => {children} ;
const Divider = () =>
;
const SLABar = ({ pct, label }) => (
{label} 75?C.red:pct>50?C.amber:C.green, fontWeight:700 }}>{pct}%
);
// ── SCREEN 0 — BLIND SPOT PREVIEW ────────────────────────────────────────────
const Screen0 = () => (
The Unfinished
Get Your Portfolio Blind Spot Preview
Upload your CAMS CAS and we'll surface 3 key findings within 24 hours. Free. No commitment.
Your Name *
Email Address *
Mobile (optional)
Upload CAMS CAS (PDF) *
📎
portfolio_cas_march2026.pdf
✓ Valid PDF · 2.4 MB · Not password-protected
Click to replace
What you'll receive in 24 hours: One finding shown in full detail, two more as headlines to preview. Your overall portfolio band. A follow-up call from our lead evaluator.
Get My Blind Spot Preview →
No commissions. No products. Independent evaluation only.
⚠ This document is password-protected. Please upload an unencrypted version.
);
// ── SCREEN 1 — CLIENT INTAKE PORTAL ─────────────────────────────────────────
const Screen1 = () => {
const [step, setStep] = useState(1);
return (
ENGAGEMENT · TU-2026-MF-0047 · TIER 2
Comprehensive Portfolio Evaluation
Submission deadline
3 days remaining
{["Profile","Documents","Goals"].map((s,i) => (
setStep(i+1)} style={{ flex: 1, textAlign: "center", padding: "8px 4px", cursor: "pointer",
borderBottom: step===i+1 ? `2px solid ${C.gold}` : "2px solid rgba(255,255,255,0.1)",
color: step===i+1 ? C.gold : "rgba(255,255,255,0.4)", fontSize: 11, fontWeight: step===i+1 ? 700 : 400 }}>
{i+1{s}
))}
{step===1 && (
Step 1 — Your Profile
Pre-filled from your registration. Please verify.
{[["Full Name","Priya Sharma"],["PAN Number","ABCPS1234P"],["Date of Birth","15 / 08 / 1981"],["Mobile","+91 98765 43210"],["Email","priya.sharma@email.com"],["City","Mumbai"]].map(([l,v]) => (
{l}
))}
setStep(2)}>Continue to Documents →
)}
{step===2 && (
Step 2 — Upload Documents
Documents required for Tier 2 — Comprehensive Evaluation
{[
{ name: "CAMS CAS (Mutual Funds)", status: "validated", required: true, size: "2.4 MB" },
{ name: "KFintech CAS (if applicable)", status: "not_uploaded", required: false },
{ name: "Demat Statement (CDSL/NSDL)", status: "validated", required: false, size: "1.1 MB" },
{ name: "Goal & Profile Questionnaire", status: "pending", required: true, note: "Complete in Step 3" },
].map(doc => (
{doc.status==="validated"?"✅":doc.status==="pending"?"🔄":"📋"}
{doc.name} {doc.required && * }
{doc.status==="validated"?`Validated · ${doc.size}`:doc.status==="pending"?doc.note:"Not uploaded · Optional"}
{doc.status!=="pending" &&
{doc.status==="validated"?"Replace":"Upload"} }
))}
setStep(1)}>← Back
setStep(3)}>Continue to Goals →
)}
{step===3 && (
Step 3 — Goals & Profile
Required for Tier 2. All fields marked * are mandatory.
{[["Primary Goal *","Wealth Growth"],["Risk Tolerance *","Moderate"],["Retirement Age *","60"],["Current Age","43"],["Monthly Income Range *","₹5L – ₹10L"],["Monthly SIP Amount *","₹1,20,000"]].map(([l,v]) => (
{l}
))}
Number of Children & Ages
Major Planned Expenses (next 5 years) — Optional
setStep(2)}>← Back
Submit Intake ✓
)}
);
};
// ── SCREEN 2 — OPS VIEW ──────────────────────────────────────────────────────
const Screen2 = () => (
{[["Total Active","14",C.navy],["Ready to Evaluate","3",C.green],["Data Incomplete","4",C.amber],["SLA Warning","2",C.red]].map(([l,v,c]) => (
))}
Active Submissions Pipeline
Filter ▾
{["Engagement ID","Client / IFA","Tier","Status","SLA Remaining","Action"].map(h => {h} )}
{[
{ id:"TU-2026-MF-0047", name:"Priya Sharma (Direct)", tier:"T2", status:"Ready to Evaluate", sla:62, slac:"green" },
{ id:"TU-2026-MF-0048", name:"Arjun Capital / HDFC IFA", tier:"T3", status:"Ready to Evaluate", sla:88, slac:"red" },
{ id:"TU-2026-MF-0045", name:"Mehta Family (Direct)", tier:"T3", status:"Data Incomplete", sla:0, slac:"grey" },
{ id:"TU-2026-MF-0046", name:"Clarity Wealth / IFA", tier:"T1", status:"Awaiting Intake", sla:0, slac:"grey" },
{ id:"TU-2026-MF-0044", name:"Sunita Rao (Direct)", tier:"T2", status:"Evaluation In Progress", sla:41, slac:"amber" },
].map((r,i) => (
{r.id}
{r.name}
{r.tier}
{r.status}
{r.sla>0 ? <>
{r.sla}% elapsed
> : Timer not started }
{r.status==="Ready to Evaluate" && Mark Complete ✓ }
{r.status==="Data Incomplete" && Request Docs }
{r.status==="Awaiting Intake" && View Details }
))}
);
// ── SCREEN 3 — EVALUATION CONSOLE ────────────────────────────────────────────
const Screen3 = () => {
const [selected, setSelected] = useState("PS-07");
const factors = [
{ id:"PS-01", name:"Asset Allocation", grade:"D", status:"evaluated" },
{ id:"PS-02", name:"Equity-Debt-Gold", grade:"D", status:"evaluated" },
{ id:"PS-03", name:"Market Cap Dist.", grade:"C", status:"evaluated" },
{ id:"PS-05", name:"AMC Concentration", grade:"B", status:"evaluated" },
{ id:"PS-07", name:"Single Fund Conc.", grade:"C", status:"evaluated", active:true },
{ id:"CA-01", name:"Blended TER", grade:"A", status:"evaluated" },
{ id:"CA-02", name:"Direct vs Regular", grade:"A", status:"evaluated" },
{ id:"CA-06", name:"IDCW vs Growth", grade:"A", status:"evaluated" },
{ id:"OR-01", name:"Folio Duplication", grade:"C", status:"evaluated" },
{ id:"OR-03", name:"Unique Positions", grade:"C", status:"evaluated" },
{ id:"GA-01", name:"Corpus Sufficiency", grade:null, status:"not_evaluated" },
{ id:"IP-01", name:"Life Cover", grade:null, status:"not_evaluated" },
];
return (
{/* Left: portfolio summary */}
Portfolio Summary
{[["Total AUM","₹89.1L"],["Schemes","21"],["Fund Houses","7"],["Direct Plans","99.9%"],["Debt %","0%"]].map(([l,v]) => (
{l} {v}
))}
Scope Coverage
10 / 55 factors
8 NE (missing docs)
{/* Centre: factor list */}
PS — Portfolio Structure
{factors.filter(f=>f.id.startsWith("PS")).map(f => (
setSelected(f.id)} style={{ display:"flex", gap:8, alignItems:"center", padding:"6px 8px", borderRadius:4, cursor:"pointer",
background: selected===f.id ? C.lnavy : "transparent", marginBottom:2 }}>
{f.grade||"NE"}
{f.name}
))}
CA — Cost Architecture
{factors.filter(f=>f.id.startsWith("CA")).map(f => (
setSelected(f.id)} style={{ display:"flex", gap:8, alignItems:"center", padding:"6px 8px", borderRadius:4, cursor:"pointer",
background: selected===f.id ? C.lnavy : "transparent", marginBottom:2 }}>
{f.grade}
{f.name}
))}
GA / IP — Not Evaluated
{factors.filter(f=>f.status==="not_evaluated").map(f => (
))}
{/* Right: finding editor */}
PS-07 · Portfolio Structure
Single Fund Concentration Risk
C
Data inputs: SBI Small Cap Fund = ₹25.78L = 28.9% of total AUM. Threshold: 20%. Excess: 8.9 percentage points.
Severity
{["High","Medium","Low","Positive"].map(s => (
{s}
))}
Layer 1 — Analyst Detail (technical, not shared with client)
Layer 2 — Client Narrative (plain English, forward-looking)
✓ Text is distinct from Layer 1
Recommendation
← Previous Factor
Next Factor →
Submit All for Review ✓
);
};
// ── SCREEN 4 — LEAD EVALUATOR REVIEW ────────────────────────────────────────
const Screen4 = () => (
TU-2026-MF-0047 · TIER 2 · PRIYA SHARMA
Lead Evaluator Review Console
SLA Status
18 hrs remaining
🔒 Execute Data Lock
{[["PS","D"],["CA","A"],["OR","C"],["AQ","B"],["RC","D"],["GA","NE"],["IP","NE"],["ES","B"]].map(([b,g]) => (
))}
{[
{ id:"PS-01", block:"PS", name:"Asset Allocation vs Risk Profile", grade:"D", sev:"High", status:"pending", detail:"Portfolio is 99.9% equity, 0% debt. Client risk profile is 'Moderate'. This is a direct contradiction requiring immediate attention." },
{ id:"PS-07", block:"PS", name:"Single Fund Concentration", grade:"C", sev:"High", status:"approved", detail:"SBI Small Cap at 28.9% — exceeds 20% threshold by 8.9pp. Partial switch-out on 10-Apr-2026 noted." },
{ id:"CA-02", block:"CA", name:"Direct vs Regular Plan", grade:"A", sev:"Positive", status:"approved", detail:"99.9% Direct plans. Only one legacy Regular folio (₹892 — negligible). Trail savings ~₹7,200/year." },
{ id:"OR-01", block:"OR", name:"Folio Duplication", grade:"C", sev:"Medium", status:"returned", detail:"5 confirmed duplicate folio pairs across HDFC Flexi Cap, HDFC Midcap 150, SBI ELSS, ICICI Tech, and SBI Small Cap." },
].map(f => (
{f.name}
{f.detail}
{f.status==="pending" && (
✓ Approve
✎ Modify
↩ Return
)}
{f.status==="approved" &&
✓ Approved }
{f.status==="returned" &&
↩ Returned for revision }
))}
⚠ Data Lock Not Yet Available
2 findings are pending your review. Approve or return all findings before executing the data lock.
);
// ── SCREEN 5 — CLIENT REPORT PORTAL ─────────────────────────────────────────
const Screen5 = () => {
const [tab, setTab] = useState("summary");
return (
THE UNFINISHED · INDEPENDENT PORTFOLIO EVALUATION · APRIL 2026
Your Portfolio Evaluation
Priya Sharma · ₹89.1L · 21 schemes · April 2026
Overall Grade
C+
Needs attention
{["summary","report","actions","documents"].map(t => (
setTab(t)} style={{ flex:1, background:"transparent", border:"none", cursor:"pointer",
padding:"8px 4px", color:tab===t?C.gold:"rgba(255,255,255,0.35)", fontWeight:tab===t?700:400,
fontSize:11, borderBottom:tab===t?`2px solid ${C.gold}`:"2px solid transparent", textTransform:"capitalize" }}>{t==="actions"?"Actions (10)":t==="report"?"Full Report":t.charAt(0).toUpperCase()+t.slice(1)}
))}
{tab==="summary" && (
{[["PS · Structure","D"],["CA · Cost","A"],["OR · Overlap","C"],["AQ · Advisor","B"]].map(([l,g]) => (
))}
3 Most Important Findings
Start with these in your review conversation.
{[
{ n:1, head:"Your portfolio has zero debt allocation", detail:"Your entire portfolio is in equity. We recommend building a debt buffer — even ₹10–15 lakhs in a liquid fund — as a safety layer.", sev:"High" },
{ n:2, head:"Your largest holding is too concentrated", detail:"SBI Small Cap Fund is 29% of your portfolio. Best practice is under 20%. We have a plan to reduce this gradually.", sev:"High" },
{ n:3, head:"Five funds are held in duplicate folios", detail:"The same scheme in multiple folios creates admin complexity. Consolidating will simplify your portfolio significantly.", sev:"Medium" },
].map(f => (
{f.n}
{f.head}
{f.sev}
{f.detail}
))}
)}
{tab==="actions" && (
Your Action Register
10 recommendations · Update your status as you act on each
{["#","Recommendation","Priority","Your Status",""].map(h=>{h} )}
{[
{ n:1, rec:"Start a liquid fund SIP of ₹50,000/month to build debt buffer", p:"High", status:"Accepted" },
{ n:2, rec:"Set up STP from SBI Small Cap to Nifty 50 Index — ₹5,000/month", p:"High", status:"Pending" },
{ n:3, rec:"Consolidate HDFC Flexi Cap folios (3 folios → 1)", p:"Medium", status:"In Progress" },
{ n:4, rec:"Switch ICICI Tech folio duplication to primary folio", p:"Medium", status:"Pending" },
{ n:5, rec:"Review SBI Gold Fund switch on 10-Apr — was this intentional?", p:"Medium", status:"Deferred" },
].map((r,i) => (
{r.n}
{r.rec}
{r.p}
{r.status}
Update
))}
)}
);
};
// ── SCREEN 6 — RETAINER DASHBOARD ────────────────────────────────────────────
const Screen6 = () => (
RETAINER · TIER 2 · Q3 CYCLE
Priya Sharma
{[["Next Cycle","Q4 · Jan 2027"],["Annual Renewal","92 days"],["Grade Trend","↑ Improving"]].map(([l,v]) => (
))}
Upload Updated CAS
Last uploaded: 15 Oct 2026
Upload CAMS CAS ↑
⚠ 2 Unacknowledged High-Priority Alerts
{[
{ type:"Allocation Drift", detail:"Equity drifted to 81% — target 70%. ±5% tolerance exceeded." },
{ type:"Regular Plan Detected", detail:"New Regular plan folio detected in Oct CAS — SBI Balanced Advantage." },
].map(a => (
{a.type}
{a.detail}
Acknowledge
))}
Portfolio Drift — Q3 Monitor
{["Asset Class","Target","Q2","Q3","Δ"].map(h=>{h} )}
{[["Equity","70%","75%","81% ","+6pp"],["Debt","15%","13%","11%","−4pp"],["Gold","8%","9%","6%","−3pp"],["Cash","7%","3%","2%","−1pp"]].map(([c,t,q2,q3,d],i) => (
{c} {t} {q2} {d}
))}
Open Recommendations
{[
{ n:1, rec:"Start liquid fund SIP ₹50K/month", status:"In Progress", age:"6 months" },
{ n:2, rec:"Reduce SBI Small Cap to below 20%", status:"Pending", age:"6 months" },
{ n:5, rec:"Review SBI Gold Fund switch (Apr 26)", status:"Deferred", age:"Revisit Dec 2026" },
].map((r,i) => (
))}
);
// ── SCREEN 7 — ADMIN CONSOLE ─────────────────────────────────────────────────
const Screen7 = () => (
{[["Active Engagements","14",C.navy],["SLA Warnings","2",C.red],["Open Alerts","5",C.amber],["IFA Partners","8",C.teal]].map(([l,v,c]) => (
))}
Engagement Pipeline
Export CSV
+ New Engagement
{["ID","Client","Tier","Status","SLA"].map(h=>{h} )}
{[
{ id:"0047", c:"Priya Sharma", t:"T2", s:"Evaluation In Progress", sla:41, sc:"amber" },
{ id:"0048", c:"Arjun Capital/IFA", t:"T3", s:"Ready to Evaluate", sla:88, sc:"red" },
{ id:"0049", c:"Mehta Family", t:"T3", s:"Data Incomplete", sla:0, sc:"grey" },
{ id:"0050", c:"Sanjay Shah", t:"T1", s:"Delivered", sla:100, sc:"green" },
].map((r,i) => (
TU-2026-MF-{r.id}
{r.c}
{r.t}
{r.s}
{r.sla>0 ? : — }
))}
AMFI Data Status
Last refresh: Today 06:30 IST
{[["NAVAll.txt","✓ 1,847 schemes"],["mfapi.in","✓ Connected"],["Enricher","✓ Last run 2h ago"]].map(([l,v]) => (
{l} {v}
))}
↻ Manual Refresh
Alert Queue
{[
{ type:"Allocation Drift", client:"Priya Sharma", sev:"High" },
{ type:"Regular Plan Detected", client:"Priya Sharma", sev:"High" },
{ type:"Fund Q4 Drop", client:"Arjun Capital", sev:"Medium" },
].map((a,i) => (
))}
);
// ── MAIN APP ─────────────────────────────────────────────────────────────────
const SCREENS = [
{ id:"s0", label:"Screen 0", sub:"Blind Spot Preview", icon:"🔍", component:Screen0 },
{ id:"s1", label:"Screen 1", sub:"Client Intake Portal", icon:"📝", component:Screen1 },
{ id:"s2", label:"Screen 2", sub:"Ops Submission View", icon:"🗂", component:Screen2 },
{ id:"s3", label:"Screen 3", sub:"Evaluation Console", icon:"⚡", component:Screen3 },
{ id:"s4", label:"Screen 4", sub:"Lead Evaluator Review", icon:"✅", component:Screen4 },
{ id:"s5", label:"Screen 5", sub:"Client Report Portal", icon:"📊", component:Screen5 },
{ id:"s6", label:"Screen 6", sub:"Retainer Dashboard", icon:"🔄", component:Screen6 },
{ id:"s7", label:"Screen 7", sub:"Admin Console", icon:"⚙️", component:Screen7 },
];
export default function App() {
const [active, setActive] = useState("s0");
const current = SCREENS.find(s => s.id === active);
const Component = current.component;
return (
The Unfinished
·
{current.icon} {current.label} — {current.sub}
Product Screens
{SCREENS.map(s => (
setActive(s.id)}>
{s.icon}
))}
);
}