diff options
| -rw-r--r-- | frontend/app/page.tsx | 20 | ||||
| -rw-r--r-- | frontend/app/prism-shell.css | 50 | ||||
| -rw-r--r-- | frontend/components/prism/TickerHeader.tsx | 14 |
3 files changed, 58 insertions, 26 deletions
diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index 41408b0..013b93d 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx @@ -511,6 +511,9 @@ function StatsCard({ overview }: { overview: TickerOverview }) { { label: "Payout Ratio", value: fmtPct(overview.ratios.dividend_payout_ratio_ttm), missing: overview.ratios.dividend_payout_ratio_ttm == null } ]; + const visibleRows = referenceRows.filter((r) => !r.missing); + const suppressedCount = referenceRows.length - visibleRows.length; + return ( <section className="psm-card"> <div className="psm-card-head"> @@ -519,11 +522,18 @@ function StatsCard({ overview }: { overview: TickerOverview }) { <h2 className="psm-card-title">Reference</h2> </div> </div> - <div className="psm-stat-list"> - {referenceRows.map((row) => ( - <StatRow key={row.label} label={row.label} value={row.value} missing={row.missing} /> - ))} - </div> + {visibleRows.length > 0 && ( + <div className="psm-stat-list"> + {visibleRows.map((row) => ( + <StatRow key={row.label} label={row.label} value={row.value} missing={false} /> + ))} + </div> + )} + {suppressedCount > 0 && ( + <p className="psm-muted-copy" style={{ marginTop: visibleRows.length > 0 ? "var(--sp-4)" : 0 }}> + ยท Statement data incomplete + </p> + )} </section> ); } diff --git a/frontend/app/prism-shell.css b/frontend/app/prism-shell.css index b6372c2..6ccf9ca 100644 --- a/frontend/app/prism-shell.css +++ b/frontend/app/prism-shell.css @@ -509,32 +509,48 @@ min-width: 0; } -.psm-head-meta { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 8px; - margin-bottom: var(--sp-3); -} - -.psm-identity-line { +.psm-sector-label { + display: block; + font-family: var(--font-sans); + font-size: var(--fs-12); + font-weight: 600; + text-transform: uppercase; + letter-spacing: var(--tr-wider); color: var(--brass); - display: inline-flex; + margin-bottom: var(--sp-2); } .psm-heading-row { display: flex; + align-items: baseline; + gap: var(--sp-4); flex-wrap: wrap; - align-items: flex-start; - gap: var(--sp-3); } -.psm-company-name { +.psm-company-sym { + font-family: var(--font-display); + font-size: var(--fs-64); + font-weight: 500; color: var(--fg-1); + line-height: 0.95; + letter-spacing: -0.025em; +} + +.psm-company-name { font-family: var(--font-display); - font-size: clamp(2.8rem, 5vw, var(--fs-56)); + font-size: var(--fs-24); font-style: italic; - line-height: 0.95; + color: var(--fg-2); + font-weight: 400; + line-height: 1; +} + +.psm-head-meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px; + margin-top: var(--sp-2); } .psm-partial-chip, @@ -777,6 +793,10 @@ background: linear-gradient(180deg, rgba(194, 170, 122, 0.03), rgba(194, 170, 122, 0)); } +.psm-chart-frame .chart { + width: 100%; +} + .psm-chart-meta { color: var(--fg-3); font-size: var(--fs-13); diff --git a/frontend/components/prism/TickerHeader.tsx b/frontend/components/prism/TickerHeader.tsx index 369d06c..804ffc0 100644 --- a/frontend/components/prism/TickerHeader.tsx +++ b/frontend/components/prism/TickerHeader.tsx @@ -1,5 +1,5 @@ import { deltaClass, fmtCurrency, fmtPct } from "@/lib/format"; -import { buildIdentityLine, rangePercent } from "@/lib/overview"; +import { rangePercent } from "@/lib/overview"; import type { TickerOverview } from "@/types/api"; type Props = { @@ -15,15 +15,17 @@ export function TickerHeader({ overview, onToggleWatchlist, isSaved }: Props) { return ( <header className="psm-ticker-head"> <div className="psm-header-left"> + {overview.profile.sector && ( + <span className="psm-sector-label">{overview.profile.sector}</span> + )} + <div className="psm-heading-row"> + <span className="psm-company-sym">{overview.profile.symbol}</span> + <span className="psm-company-name">{overview.profile.name || "Name unavailable"}</span> + </div> <div className="psm-head-meta"> - <span className="psm-identity-line psm-eyebrow">{overview.profile.symbol}</span> {overview.profile.exchange ? <span className="psm-tag">{overview.profile.exchange}</span> : null} {overview.meta.is_partial ? <span className="psm-partial-chip">Partial Data</span> : null} </div> - <div className="psm-heading-row"> - <span className="psm-company-name">{overview.profile.name || "Name unavailable"}</span> - </div> - <p className="psm-subline">{buildIdentityLine(overview)}</p> </div> <div className="psm-range"> |
