vitals / static /index.html
s-ttp's picture
Six-pillar health score with visible breakdown; prospects pillar; profile-weighted drawdown efficiency
988e3ef verified
Raw History Blame Contribute Delete
12.8 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Vitals</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path d='M1 21 h6 l3 -7 l5 12 l4 -17 l4 12 h8' stroke='%2338dbff' fill='none' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'/><path fill='%23f2c744' d='M24 2 C24 5.2, 24.8 6, 28 6 C24.8 6, 24 6.8, 24 10 C24 6.8, 23.2 6, 20 6 C23.2 6, 24 5.2, 24 2 Z'/></svg>">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600;9..144,700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<header>
<div class="brand">
<svg class="mark" viewBox="0 0 40 34" width="52" height="44" aria-hidden="true">
<path d="M2 21 h8 l3 -7 l5 12 l4 -17 l4 12 h8" stroke="var(--accent)" fill="none"
stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
<g fill="#f2c744">
<path class="spark s1" d="M31 3 C31 6.2, 31.8 7, 35 7 C31.8 7, 31 7.8, 31 11 C31 7.8, 30.2 7, 27 7 C30.2 7, 31 6.2, 31 3 Z"/>
<path class="spark s2" d="M7 4.5 C7 6.6, 7.5 7.1, 9.6 7.1 C7.5 7.1, 7 7.6, 7 9.7 C7 7.6, 6.5 7.1, 4.4 7.1 C6.5 7.1, 7 6.6, 7 4.5 Z"/>
<path class="spark s3" d="M37.2 14 C37.2 15.5, 37.6 15.9, 39.1 15.9 C37.6 15.9, 37.2 16.3, 37.2 17.8 C37.2 16.3, 36.8 15.9, 35.3 15.9 C36.8 15.9, 37.2 15.5, 37.2 14 Z"/>
</g>
</svg>
<b>Vitals</b>
</div>
<div class="tagline">Your portfolio's AI health check</div>
</header>
<!-- ═══════════ VIEW 1 Β· INPUT ═══════════ -->
<main id="view-input" class="view">
<div class="ticker-wrap" id="ticker-wrap" hidden>
<div class="ticker" id="ticker"></div>
</div>
<section class="card code-card">
<div class="code-row">
<span class="code-label">Returning? Enter your case ID</span>
<input id="code-input" maxlength="8" placeholder="e.g. 3f9a2c1b">
<button class="ghost" id="load-code">Open case</button>
<span id="code-status" class="code-status"></span>
</div>
</section>
<section class="card watch-card" id="watch-card" hidden>
<h2>Standing watch β€” <span id="watch-code"></span></h2>
<div id="track-record" class="track"></div>
<div id="watch-alerts" class="alerts"></div>
<div class="row-actions" style="margin:12px 0 0">
<button class="ghost" id="check-now">Check now (prices, trends &amp; news events)</button>
<span id="check-status" class="code-status"></span>
</div>
</section>
<section class="card intro-card">
<h1>What's in your portfolio?</h1>
<p class="sub">Key in each holding β€” ticker or company name, and the price you bought at.
Quantity is optional (without it, positions are treated as equal-sized).</p>
<table id="input-table">
<thead><tr>
<th>Ticker / company</th><th>Entry&nbsp;price</th><th>Qty <span class="opt">(optional)</span></th>
<th>Bought <span class="opt">(optional)</span></th>
<th class="resolved-col"></th><th></th>
</tr></thead>
<tbody id="rows"></tbody>
</table>
<div class="row-actions">
<button class="ghost" id="add-row">+ Add holding</button>
<button class="ghost" id="import-file">πŸ“„ Import file (CSV Β· Excel Β· PDF)</button>
<button class="ghost" id="load-sample">Load sample portfolio</button>
<input type="file" id="file-input" accept=".csv,.tsv,.txt,.xlsx,.xls,.pdf" hidden>
</div>
<div class="hint" id="import-status" hidden></div>
<div class="hint">Tip: quantities are optional, but adding them unlocks exact weights,
true P/L and dollar trade sizes in the plan. Bought at several prices? Enter each purchase
on its own row β€” same ticker, its price and quantity β€” and the average cost is worked out
for you (a negative quantity records a sale).</div>
<details class="ctx" id="ctx-panel">
<summary>Optional β€” tell the analysts about yourself, and they will also draft a <b>recommended target portfolio</b></summary>
<div class="ctx-grid">
<label>Investment horizon
<select id="ctx-horizon">
<option value="">β€”</option>
<option value="under 3 years">Under 3 years</option>
<option value="3-7 years">3–7 years</option>
<option value="7+ years">7+ years</option>
</select></label>
<label>Risk appetite
<select id="ctx-risk">
<option value="">β€”</option>
<option value="conservative">Conservative</option>
<option value="balanced">Balanced</option>
<option value="aggressive">Aggressive</option>
</select></label>
<label>Objective
<select id="ctx-objective">
<option value="">β€”</option>
<option value="growth">Growth</option>
<option value="income">Income</option>
<option value="balanced growth and income">Growth + income</option>
</select></label>
<label>Worst one-year drop you could stomach
<select id="ctx-loss">
<option value="">β€”</option>
<option value="10%">About 10%</option>
<option value="20%">About 20%</option>
<option value="35%">About 35%</option>
<option value="50% or more">50% or more</option>
</select></label>
<label>Need some of this money within 2 years?
<select id="ctx-liq">
<option value="">β€”</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select></label>
<label>Exclusions <span class="opt">(comma-separated: tickers, sectors, words)</span>
<input id="ctx-excl" placeholder="e.g. tobacco, MO, weapons"></label>
<label>Account wrapper
<select id="ctx-wrapper">
<option value="">β€”</option>
<option value="taxable">Taxable</option>
<option value="isa">ISA</option>
<option value="sipp">SIPP / pension</option>
<option value="ira">IRA / 401k</option>
</select></label>
<label>Max number of positions
<select id="ctx-maxpos">
<option value="">β€”</option>
<option value="8">8</option>
<option value="12">12</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="30">30</option>
</select></label>
</div>
</details>
<button id="analyze" class="primary">Check my portfolio's vitals</button>
<div class="microcopy">Five AI analysts across Claude, GPT &amp; Gemini + Damodaran valuation Β· verdict in ~90 seconds</div>
<div id="input-error" class="input-error" hidden></div>
</section>
</main>
<!-- ═══════════ VIEW 2 Β· ANALYZING ═══════════ -->
<main id="view-progress" class="view" hidden>
<section class="card progress-card">
<h2 id="progress-caption">Reading your vitals…</h2>
<div class="bar-track"><div class="bar-fill" id="bar"></div></div>
<div class="chips" id="chips">
<span class="chip" data-chip="value">πŸ› Value</span>
<span class="chip" data-chip="growth">πŸš€ Growth</span>
<span class="chip" data-chip="macro">🌍 Macro</span>
<span class="chip" data-chip="technical">πŸ“ˆ Technical</span>
<span class="chip" data-chip="risk">πŸ›‘ Risk</span>
<span class="chip" data-chip="cio">🎯 CIO</span>
</div>
<div class="skeleton">
<div class="sk sk-hero"></div>
<div class="sk-row"><div class="sk"></div><div class="sk"></div><div class="sk"></div></div>
<div class="sk sk-table"></div>
</div>
</section>
</main>
<!-- ═══════════ VIEW 3 Β· RESULTS ═══════════ -->
<main id="view-results" class="view" hidden>
<section class="hero card">
<div class="gauge-wrap">
<svg id="gauge" viewBox="0 0 200 120" width="220">
<path d="M20 110 A 90 90 0 0 1 180 110" fill="none" stroke="var(--line)" stroke-width="14" stroke-linecap="round"/>
<path id="gauge-arc" d="M20 110 A 90 90 0 0 1 180 110" fill="none" stroke="var(--good)" stroke-width="14" stroke-linecap="round"/>
<text id="gauge-num" x="100" y="95" text-anchor="middle">–</text>
<text x="100" y="114" text-anchor="middle" class="gauge-label">portfolio health</text>
</svg>
<div id="health-pillars" class="pillars" hidden></div>
</div>
<div class="hero-text">
<div id="verdict" class="verdict"></div>
<div id="action-strip" class="action-strip"></div>
<div id="approx-banner" class="approx-banner" hidden>
βš–οΈ Approximate mode β€” no quantities were given, so positions are treated as
equal-sized. Add quantities for exact concentration, P/L and trade sizes.
</div>
</div>
</section>
<section class="card">
<h2>Key findings</h2>
<div id="highlights" class="highlights"></div>
</section>
<section class="card">
<h2>Recommendations</h2>
<div class="table-scroll">
<table id="rec-table">
<thead><tr><th>Holding</th><th>Weight</th><th>P/L</th><th>vs&nbsp;intrinsic</th><th>Action</th><th>Why</th></tr></thead>
<tbody id="rec-body"></tbody>
</table>
</div>
<div class="hint">Click a row for the committee detail on that holding.</div>
</section>
<section class="card" id="plan-section" hidden>
<h2 id="plan-title"></h2>
<div id="plan-pitch" class="plan-pitch"></div>
<div id="plan-moves" class="plan-moves"></div>
<div id="plan-pairs" class="plan-pairs"></div>
<div id="plan-outlook" class="plan-outlook"></div>
<div id="plan-extra" class="plan-extra" hidden></div>
<div id="plan-construction" class="plan-construction"></div>
<details class="plan-details"><summary>Order plan β€” the trades to get there</summary>
<div class="table-scroll">
<table id="plan-orders" class="mini-table">
<thead><tr><th></th><th>Holding</th><th>Size</th><th>Approx.</th></tr></thead>
<tbody id="plan-orders-body"></tbody>
</table>
</div>
<div class="hint" id="plan-orders-note"></div>
</details>
<details class="plan-details" id="plan-triage-wrap"><summary>Losing-position triage</summary>
<div id="plan-triage"></div>
</details>
</section>
<section class="card two-col">
<div>
<h2>Sector mix</h2>
<svg id="donut" viewBox="0 0 200 200" width="210"></svg>
<div id="donut-legend" class="legend"></div>
</div>
<div>
<h2>Position sizes</h2>
<div id="weight-bars" class="weight-bars"></div>
<div class="hint" id="cap-hint"></div>
</div>
</section>
<section class="card">
<h2>Risk scorecard</h2>
<div id="scorecard" class="scorecard"></div>
<div id="strategy-read" class="strategy-read"></div>
</section>
<section class="card" id="risk-section" hidden>
<h2>Risk analytics</h2>
<div id="risk-body" class="risk-body"></div>
</section>
<section class="card" id="alt-section" hidden>
<h2>Worth a look β€” gap fillers</h2>
<div id="alternatives" class="alt-cards"></div>
</section>
<section class="card" id="rejected-section" hidden>
<details><summary>Considered but not recommended</summary>
<div id="rejected-body" class="rejected-body"></div></details>
</section>
<section class="card" id="target-section" hidden>
<h2>Recommended target portfolio</h2>
<div id="target-note" class="hint" style="margin:0 0 12px"></div>
<div class="table-scroll">
<table id="target-table">
<thead><tr><th>Holding</th><th>Sector</th><th>Current</th><th>Target</th><th>Change</th></tr></thead>
<tbody id="target-body"></tbody>
</table>
</div>
</section>
<footer class="card footer">
<div class="footer-actions">
<a id="download" class="primary" href="#" download>Download full report (PDF)</a>
<a id="audit" class="ghost" href="#" download>Audit trail (JSON)</a>
<button class="ghost" id="save-track">πŸ’Ύ Save &amp; track this portfolio</button>
<button class="ghost" id="rerun">β†Ί New analysis</button>
</div>
<div id="save-result" class="save-result" hidden></div>
<div id="meta" class="meta"></div>
<div id="disclaimer" class="disclaimer"></div>
</footer>
</main>
<script src="/static/app.js"></script>
</body>
</html>