summaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authorTyler Hoang <tyler@tylerhoang.xyz>2026-05-19 00:52:16 -0700
committerTyler Hoang <tyler@tylerhoang.xyz>2026-05-19 00:52:16 -0700
commite8ab8993949e960af931f24913d32a5c023bab97 (patch)
tree8903101f930542fe326f7f495bdd6f0311b90dbe /frontend
parent5fd350345a6f6caceb3375d3736a9a9ef7291257 (diff)
fix: resolve quality review issues in PriceVsValueCard
- Add 150ms ease transitions to pvv-fill and pvv-tick (design system) - Move fill color to modifier CSS classes, drop inline background/opacity - Guard iv === 0 to prevent Infinity in premium/discount label - Remove ambiguous direction arrows from IV figure - Add "projection" suffix to year count in assumption summary Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'frontend')
-rw-r--r--frontend/app/prism-shell.css5
-rw-r--r--frontend/components/prism/PriceVsValueCard.tsx14
2 files changed, 10 insertions, 9 deletions
diff --git a/frontend/app/prism-shell.css b/frontend/app/prism-shell.css
index 9bcbdc5..09b8ebd 100644
--- a/frontend/app/prism-shell.css
+++ b/frontend/app/prism-shell.css
@@ -1924,14 +1924,19 @@
top: 0;
height: 100%;
border-radius: var(--r-full);
+ transition: left 150ms ease, width 150ms ease;
}
+.psm-pvv-fill--premium { background: var(--negative); opacity: 0.5; }
+.psm-pvv-fill--discount { background: var(--positive); opacity: 0.5; }
+
.psm-pvv-tick {
position: absolute;
top: -4px;
width: 2px;
height: 12px;
border-radius: 1px;
+ transition: left 150ms ease;
}
.psm-pvv-tick.price {
diff --git a/frontend/components/prism/PriceVsValueCard.tsx b/frontend/components/prism/PriceVsValueCard.tsx
index 95124ce..cf5a3c7 100644
--- a/frontend/components/prism/PriceVsValueCard.tsx
+++ b/frontend/components/prism/PriceVsValueCard.tsx
@@ -40,6 +40,7 @@ export function PriceVsValueCard({ overview, valuation, valState }: Props) {
if (price == null) return null;
const iv = dcf.intrinsic_value_per_share;
+ if (iv === 0) return null;
const { leftPct, widthPct, pricePct, ivPct, isPremium } = barPositions(price, iv);
const pct = ((price - iv) / iv) * 100;
const pctLabel = isPremium
@@ -61,18 +62,13 @@ export function PriceVsValueCard({ overview, valuation, valState }: Props) {
<div className="psm-pvv-figures">
<span className="psm-pvv-current">{fmtCurrency(price)}</span>
<span className={`psm-pvv-iv ${isPremium ? "negative" : "positive"}`}>
- {isPremium ? "↑" : "↓"} IV {fmtCurrency(iv)}
+ IV {fmtCurrency(iv)}
</span>
</div>
<div className="psm-pvv-rail">
<div
- className="psm-pvv-fill"
- style={{
- left: `${leftPct}%`,
- width: `${widthPct}%`,
- background: isPremium ? "var(--negative)" : "var(--positive)",
- opacity: 0.5,
- }}
+ className={`psm-pvv-fill ${isPremium ? "psm-pvv-fill--premium" : "psm-pvv-fill--discount"}`}
+ style={{ left: `${leftPct}%`, width: `${widthPct}%` }}
/>
<div className="psm-pvv-tick price" style={{ left: `${pricePct}%` }} />
<div className="psm-pvv-tick iv" style={{ left: `${ivPct}%` }} />
@@ -82,7 +78,7 @@ export function PriceVsValueCard({ overview, valuation, valState }: Props) {
<span>{rightLabel}</span>
</div>
<p className="psm-pvv-meta">
- {pctLabel} · WACC {fmtPct(dcf.wacc)} · {dcf.projection_years}yr
+ {pctLabel} · WACC {fmtPct(dcf.wacc)} · {dcf.projection_years}yr projection
{dcf.growth_rate_used != null ? ` · growth ${fmtPct(dcf.growth_rate_used)}` : ""}
</p>
</section>