From 62bdd79b3473262dde5fb0a90eab34fe7bf344fd Mon Sep 17 00:00:00 2001
From: Tyler Hoang <tyler@tylerhoang.xyz>
Date: Sun, 17 May 2026 13:07:40 -0700
Subject: 'UI Shell and General Architecture'

---
 frontend/components/prism/TickerHeader.tsx | 51 ++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 frontend/components/prism/TickerHeader.tsx

(limited to 'frontend/components/prism/TickerHeader.tsx')

diff --git a/frontend/components/prism/TickerHeader.tsx b/frontend/components/prism/TickerHeader.tsx
new file mode 100644
index 0000000..23254f8
--- /dev/null
+++ b/frontend/components/prism/TickerHeader.tsx
@@ -0,0 +1,51 @@
+import { deltaClass, fmtCurrency, fmtPct } from "@/lib/format";
+import { buildIdentityLine, rangePercent } from "@/lib/overview";
+import type { TickerOverview } from "@/types/api";
+
+type Props = {
+  overview: TickerOverview;
+  onToggleWatchlist: () => void;
+  isSaved: boolean;
+};
+
+export function TickerHeader({ overview, onToggleWatchlist, isSaved }: Props) {
+  const pct = rangePercent(overview);
+
+  return (
+    <header className="psm-ticker-head">
+      <div className="psm-header-left">
+        <span className="psm-identity-line psm-eyebrow">{overview.profile.symbol}</span>
+        <div className="psm-heading-row">
+          <span className="psm-symbol">{overview.profile.symbol}</span>
+          <span className="psm-company-name">{overview.profile.name || "Name unavailable"}</span>
+          {overview.meta.is_partial ? <span className="psm-partial-chip">Partial Data</span> : null}
+        </div>
+        <p className="psm-subline">{buildIdentityLine(overview)}</p>
+      </div>
+
+      <div className="psm-range">
+        <div className="psm-eyebrow">52 Week Range</div>
+        <div className="psm-range-values">
+          <span>{fmtCurrency(overview.range_52w.low)}</span>
+          <span>{fmtCurrency(overview.range_52w.price ?? overview.quote.price)}</span>
+          <span>{fmtCurrency(overview.range_52w.high)}</span>
+        </div>
+        <div className="psm-range-rail" aria-hidden>
+          {pct != null ? <span className="psm-range-indicator" style={{ left: `${pct}%` }} /> : null}
+        </div>
+      </div>
+
+      <div className="psm-price-stack">
+        <span className="psm-price">{fmtCurrency(overview.quote.price)}</span>
+        <span className={`psm-change ${deltaClass(overview.quote.change_pct)}`}>
+          {fmtCurrency(overview.quote.change)} · {fmtPct(overview.quote.change_pct, 2, true)}
+        </span>
+        <span className="psm-quote-line">Prev close {fmtCurrency(overview.quote.prev_close)}</span>
+        <button type="button" className={`psm-primary-action${isSaved ? " subtle" : ""}`} onClick={onToggleWatchlist}>
+          {isSaved ? "Remove From Watchlist" : "Save To Watchlist"}
+        </button>
+      </div>
+    </header>
+  );
+}
+
-- 
cgit v1.3-2-g0d8e

