summaryrefslogtreecommitdiff
path: root/frontend/public
diff options
context:
space:
mode:
authorTyler Hoang <tyler@tylerhoang.xyz>2026-05-17 13:07:40 -0700
committerTyler Hoang <tyler@tylerhoang.xyz>2026-05-17 13:07:40 -0700
commit62bdd79b3473262dde5fb0a90eab34fe7bf344fd (patch)
tree84f75baf7503e1df77c8335750650a72b088468a /frontend/public
parent1482422f2f5b236cdcdff4429ae06bb55dca4083 (diff)
'UI Shell and General Architecture'
Diffstat (limited to 'frontend/public')
-rw-r--r--frontend/public/design-system/colors_and_type.css354
-rw-r--r--frontend/public/design-system/fonts/EBGaramond-Italic-VariableFont_wght.ttfbin0 -> 811012 bytes
-rw-r--r--frontend/public/design-system/fonts/EBGaramond-VariableFont_wght.ttfbin0 -> 934420 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttfbin0 -> 142108 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttfbin0 -> 133468 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttfbin0 -> 141596 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttfbin0 -> 134956 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttfbin0 -> 142204 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttfbin0 -> 133796 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttfbin0 -> 138448 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttfbin0 -> 145528 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Sans/IBMPlexSans-Italic-VariableFont_wdth,wght.ttfbin0 -> 594116 bytes
-rw-r--r--frontend/public/design-system/fonts/IBM_Plex_Sans/IBMPlexSans-VariableFont_wdth,wght.ttfbin0 -> 532740 bytes
-rw-r--r--frontend/public/design-system/grain.svg7
-rw-r--r--frontend/public/design-system/icons/chart.svg6
-rw-r--r--frontend/public/design-system/icons/clock.svg4
-rw-r--r--frontend/public/design-system/icons/command.svg4
-rw-r--r--frontend/public/design-system/icons/dollar.svg4
-rw-r--r--frontend/public/design-system/icons/folder.svg3
-rw-r--r--frontend/public/design-system/icons/ledger.svg5
-rw-r--r--frontend/public/design-system/icons/pulse.svg3
-rw-r--r--frontend/public/design-system/icons/search.svg4
-rw-r--r--frontend/public/design-system/icons/terminal.svg6
-rw-r--r--frontend/public/design-system/icons/user.svg4
-rw-r--r--frontend/public/design-system/icons/window.svg5
-rw-r--r--frontend/public/design-system/logo-monogram.svg23
-rw-r--r--frontend/public/design-system/logo-wordmark.svg24
-rw-r--r--frontend/public/design-system/prism.css365
28 files changed, 821 insertions, 0 deletions
diff --git a/frontend/public/design-system/colors_and_type.css b/frontend/public/design-system/colors_and_type.css
new file mode 100644
index 0000000..59877f1
--- /dev/null
+++ b/frontend/public/design-system/colors_and_type.css
@@ -0,0 +1,354 @@
+/* =========================================================================
+ Tyler Hoang — Colors & Type
+ Dark, traditional, polished. Finance-forward.
+ ========================================================================= */
+
+/* =========================================================================
+ LOCAL BRAND FONTS — all self-hosted, no network requests
+ ========================================================================= */
+
+/* EB Garamond — variable, both axes */
+@font-face {
+ font-family: 'EB Garamond';
+ src: url('fonts/EBGaramond-VariableFont_wght.ttf') format('truetype-variations'),
+ url('fonts/EBGaramond-VariableFont_wght.ttf') format('truetype');
+ font-weight: 400 800;
+ font-style: normal;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'EB Garamond';
+ src: url('fonts/EBGaramond-Italic-VariableFont_wght.ttf') format('truetype-variations'),
+ url('fonts/EBGaramond-Italic-VariableFont_wght.ttf') format('truetype');
+ font-weight: 400 800;
+ font-style: italic;
+ font-display: swap;
+}
+
+/* IBM Plex Sans — variable, both axes (wdth + wght) */
+@font-face {
+ font-family: 'IBM Plex Sans';
+ src: url('fonts/IBM_Plex_Sans/IBMPlexSans-VariableFont_wdth,wght.ttf') format('truetype-variations'),
+ url('fonts/IBM_Plex_Sans/IBMPlexSans-VariableFont_wdth,wght.ttf') format('truetype');
+ font-weight: 100 700;
+ font-stretch: 85% 100%;
+ font-style: normal;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'IBM Plex Sans';
+ src: url('fonts/IBM_Plex_Sans/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf') format('truetype-variations'),
+ url('fonts/IBM_Plex_Sans/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf') format('truetype');
+ font-weight: 100 700;
+ font-stretch: 85% 100%;
+ font-style: italic;
+ font-display: swap;
+}
+
+/* IBM Plex Mono — static weights 300 / 400 / 500 / 600 (roman + italic) */
+@font-face {
+ font-family: 'IBM Plex Mono';
+ src: url('fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf') format('truetype');
+ font-weight: 300;
+ font-style: normal;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'IBM Plex Mono';
+ src: url('fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf') format('truetype');
+ font-weight: 300;
+ font-style: italic;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'IBM Plex Mono';
+ src: url('fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf') format('truetype');
+ font-weight: 400;
+ font-style: normal;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'IBM Plex Mono';
+ src: url('fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf') format('truetype');
+ font-weight: 400;
+ font-style: italic;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'IBM Plex Mono';
+ src: url('fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf') format('truetype');
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'IBM Plex Mono';
+ src: url('fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf') format('truetype');
+ font-weight: 500;
+ font-style: italic;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'IBM Plex Mono';
+ src: url('fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf') format('truetype');
+ font-weight: 600;
+ font-style: normal;
+ font-display: swap;
+}
+@font-face {
+ font-family: 'IBM Plex Mono';
+ src: url('fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf') format('truetype');
+ font-weight: 600;
+ font-style: italic;
+ font-display: swap;
+}
+
+:root {
+ /* ---------- COLOR — Surfaces (warm-cool ink, never pure black) ---------- */
+ --ink-0: #0B0E13; /* page background — deep midnight, hint of blue */
+ --ink-1: #11151C; /* card / surface 1 */
+ --ink-2: #181D26; /* surface 2 — popovers, raised */
+ --ink-3: #222934; /* surface 3 — input fills */
+ --ink-4: #2C3340; /* surface 4 — hover */
+
+ /* ---------- COLOR — Lines ---------- */
+ --line-1: #232934; /* hairline divider */
+ --line-2: #2E3645; /* default border */
+ --line-3: #3D4658; /* prominent border / focus ring base */
+
+ /* ---------- COLOR — Foreground (warm cream — never pure white) ---------- */
+ --fg-1: #F2ECDC; /* high — headings, primary text */
+ --fg-2: #C7C0AE; /* mid — body text */
+ --fg-3: #8E8676; /* low — secondary, captions */
+ --fg-4: #5E5849; /* lowest — disabled, tertiary */
+
+ /* ---------- COLOR — Brand accents (restrained, traditional) ---------- */
+ /* Champagne — soft, muted, never honey-gold. Confirmed by user
+ against the "Lumière" gold which read too yellow. */
+ --brass: #C2AA7A; /* primary accent — muted champagne */
+ --brass-bright: #DCC79E; /* hover / highlight — pale champagne */
+ --brass-deep: #8F7A50; /* pressed — deeper champagne */
+ --brass-ink: #17120A; /* on-brass foreground */
+
+ --oxford: #1F3D5C; /* secondary — oxford navy */
+ --oxford-light: #2E5A87;
+ --burgundy: #6E2A2E; /* tertiary — bound-leather burgundy */
+ --burgundy-light:#8B3A3F;
+
+ /* ---------- COLOR — Semantic (financial; never neon) ---------- */
+ --positive: #4F8C5E; /* gain — forest green */
+ --positive-bg: #15241A;
+ --negative: #B5494B; /* loss — muted vermilion */
+ --negative-bg: #2A1517;
+ --warning: #C49545; /* caution — amber */
+ --warning-bg: #2A1F0F;
+ --info: #4A78B5; /* info — slate blue */
+ --info-bg: #11202E;
+
+ /* ---------- COLOR — Selection / focus ---------- */
+ --focus-ring: rgba(194, 170, 122, 0.55); /* champagne at 55% */
+ --selection-bg: rgba(194, 170, 122, 0.25);
+
+ /* ---------- TYPE — Families ---------- */
+ --font-display: 'EB Garamond', 'Source Serif Pro', 'Georgia', serif;
+ --font-sans: 'IBM Plex Sans', 'Helvetica Neue', system-ui, sans-serif;
+ --font-mono: 'IBM Plex Mono', 'SF Mono', Menlo, monospace;
+
+ /* ---------- TYPE — Scale (modular, 1.250 — major third) ---------- */
+ --fs-12: 0.75rem; /* 12 — micro / labels */
+ --fs-13: 0.8125rem; /* 13 — caption */
+ --fs-14: 0.875rem; /* 14 — small */
+ --fs-16: 1rem; /* 16 — body */
+ --fs-18: 1.125rem; /* 18 — body lg */
+ --fs-20: 1.25rem; /* 20 — h6 */
+ --fs-24: 1.5rem; /* 24 — h5 */
+ --fs-30: 1.875rem; /* 30 — h4 */
+ --fs-38: 2.375rem; /* 38 — h3 */
+ --fs-48: 3rem; /* 48 — h2 */
+ --fs-64: 4rem; /* 64 — h1 */
+ --fs-88: 5.5rem; /* 88 — display */
+
+ /* ---------- TYPE — Weights ---------- */
+ --w-light: 300;
+ --w-regular: 400;
+ --w-medium: 500;
+ --w-semibold: 600;
+ --w-bold: 700;
+
+ /* ---------- TYPE — Line heights ---------- */
+ --lh-tight: 1.05;
+ --lh-snug: 1.2;
+ --lh-normal: 1.45;
+ --lh-relaxed: 1.6;
+
+ /* ---------- TYPE — Tracking ---------- */
+ --tr-tight: -0.02em;
+ --tr-snug: -0.01em;
+ --tr-normal: 0;
+ --tr-wide: 0.04em;
+ --tr-wider: 0.12em; /* small-caps labels */
+
+ /* ---------- SPACING (4px base) ---------- */
+ --sp-1: 4px;
+ --sp-2: 8px;
+ --sp-3: 12px;
+ --sp-4: 16px;
+ --sp-5: 24px;
+ --sp-6: 32px;
+ --sp-7: 48px;
+ --sp-8: 64px;
+ --sp-9: 96px;
+ --sp-10: 128px;
+
+ /* ---------- RADII — small, never bubbly ---------- */
+ --r-0: 0;
+ --r-1: 2px;
+ --r-2: 4px;
+ --r-3: 6px; /* cards default */
+ --r-4: 8px; /* large surfaces */
+ --r-full: 999px;
+
+ /* ---------- ELEVATION — long, low, warm ---------- */
+ --shadow-1: 0 1px 0 rgba(0,0,0,.4), 0 1px 2px rgba(0,0,0,.3);
+ --shadow-2: 0 1px 0 rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.45);
+ --shadow-3: 0 2px 0 rgba(0,0,0,.5), 0 12px 32px rgba(0,0,0,.55);
+ --shadow-inset: inset 0 1px 0 rgba(255,255,255,.04);
+ --shadow-brass: 0 0 0 1px rgba(194,170,122,.35), 0 6px 20px rgba(194,170,122,.18);
+}
+
+/* =========================================================================
+ SEMANTIC TYPE STYLES
+ ========================================================================= */
+
+body {
+ font-family: var(--font-sans);
+ font-size: var(--fs-16);
+ line-height: var(--lh-normal);
+ color: var(--fg-2);
+ background: var(--ink-0);
+ font-weight: var(--w-regular);
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+}
+
+::selection { background: var(--selection-bg); color: var(--fg-1); }
+
+.display, h1.display {
+ font-family: var(--font-display);
+ font-size: var(--fs-88);
+ font-weight: var(--w-regular);
+ line-height: var(--lh-tight);
+ letter-spacing: var(--tr-tight);
+ color: var(--fg-1);
+ font-style: italic; /* EB Garamond italics are the signature move */
+}
+
+h1, .h1 {
+ font-family: var(--font-display);
+ font-size: var(--fs-64);
+ font-weight: var(--w-regular);
+ line-height: var(--lh-tight);
+ letter-spacing: var(--tr-tight);
+ color: var(--fg-1);
+ margin: 0;
+}
+
+h2, .h2 {
+ font-family: var(--font-display);
+ font-size: var(--fs-48);
+ font-weight: var(--w-regular);
+ line-height: var(--lh-snug);
+ letter-spacing: var(--tr-snug);
+ color: var(--fg-1);
+ margin: 0;
+}
+
+h3, .h3 {
+ font-family: var(--font-display);
+ font-size: var(--fs-30);
+ font-weight: var(--w-medium);
+ line-height: var(--lh-snug);
+ color: var(--fg-1);
+ margin: 0;
+}
+
+h4, .h4 {
+ font-family: var(--font-sans);
+ font-size: var(--fs-20);
+ font-weight: var(--w-semibold);
+ line-height: var(--lh-snug);
+ letter-spacing: var(--tr-snug);
+ color: var(--fg-1);
+ margin: 0;
+}
+
+h5, .h5 {
+ font-family: var(--font-sans);
+ font-size: var(--fs-16);
+ font-weight: var(--w-semibold);
+ line-height: var(--lh-snug);
+ color: var(--fg-1);
+ margin: 0;
+}
+
+h6, .eyebrow {
+ font-family: var(--font-sans);
+ font-size: var(--fs-12);
+ font-weight: var(--w-semibold);
+ text-transform: uppercase;
+ letter-spacing: var(--tr-wider);
+ color: var(--fg-3);
+ margin: 0;
+}
+
+p, .p {
+ font-family: var(--font-sans);
+ font-size: var(--fs-16);
+ line-height: var(--lh-relaxed);
+ color: var(--fg-2);
+ margin: 0;
+}
+
+.lead {
+ font-family: var(--font-display);
+ font-size: var(--fs-24);
+ font-weight: var(--w-regular);
+ line-height: var(--lh-relaxed);
+ color: var(--fg-1);
+ font-style: italic;
+}
+
+.caption {
+ font-family: var(--font-sans);
+ font-size: var(--fs-13);
+ line-height: var(--lh-normal);
+ color: var(--fg-3);
+}
+
+.micro {
+ font-family: var(--font-sans);
+ font-size: var(--fs-12);
+ text-transform: uppercase;
+ letter-spacing: var(--tr-wider);
+ color: var(--fg-3);
+}
+
+code, .code {
+ font-family: var(--font-mono);
+ font-size: 0.92em;
+ background: var(--ink-3);
+ color: var(--fg-1);
+ padding: 2px 6px;
+ border-radius: var(--r-1);
+ border: 1px solid var(--line-1);
+}
+
+.tabular { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
+
+a {
+ color: var(--brass-bright);
+ text-decoration: none;
+ border-bottom: 1px solid var(--brass-deep);
+ transition: color .15s ease, border-color .15s ease;
+}
+a:hover { color: var(--fg-1); border-color: var(--brass-bright); }
diff --git a/frontend/public/design-system/fonts/EBGaramond-Italic-VariableFont_wght.ttf b/frontend/public/design-system/fonts/EBGaramond-Italic-VariableFont_wght.ttf
new file mode 100644
index 0000000..9cb1376
--- /dev/null
+++ b/frontend/public/design-system/fonts/EBGaramond-Italic-VariableFont_wght.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/EBGaramond-VariableFont_wght.ttf b/frontend/public/design-system/fonts/EBGaramond-VariableFont_wght.ttf
new file mode 100644
index 0000000..baf64b2
--- /dev/null
+++ b/frontend/public/design-system/fonts/EBGaramond-VariableFont_wght.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf
new file mode 100644
index 0000000..e259e84
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf
new file mode 100644
index 0000000..0dcb2fb
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf
new file mode 100644
index 0000000..f4a5fea
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf
new file mode 100644
index 0000000..8253c5f
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf
new file mode 100644
index 0000000..528b13b
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf
new file mode 100644
index 0000000..601ae94
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf
new file mode 100644
index 0000000..5e0b41d
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf
new file mode 100644
index 0000000..58243dd
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Sans/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf b/frontend/public/design-system/fonts/IBM_Plex_Sans/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf
new file mode 100644
index 0000000..6232aaa
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Sans/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf
Binary files differ
diff --git a/frontend/public/design-system/fonts/IBM_Plex_Sans/IBMPlexSans-VariableFont_wdth,wght.ttf b/frontend/public/design-system/fonts/IBM_Plex_Sans/IBMPlexSans-VariableFont_wdth,wght.ttf
new file mode 100644
index 0000000..9add875
--- /dev/null
+++ b/frontend/public/design-system/fonts/IBM_Plex_Sans/IBMPlexSans-VariableFont_wdth,wght.ttf
Binary files differ
diff --git a/frontend/public/design-system/grain.svg b/frontend/public/design-system/grain.svg
new file mode 100644
index 0000000..d62ad09
--- /dev/null
+++ b/frontend/public/design-system/grain.svg
@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
+ <filter id="n">
+ <feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" stitchTiles="stitch"></feTurbulence>
+ <feColorMatrix values="0 0 0 0 0.95&#xA; 0 0 0 0 0.92&#xA; 0 0 0 0 0.86&#xA; 0 0 0 0.06 0"></feColorMatrix>
+ </filter>
+ <rect width="200" height="200" filter="url(#n)"></rect>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/chart.svg b/frontend/public/design-system/icons/chart.svg
new file mode 100644
index 0000000..830d53d
--- /dev/null
+++ b/frontend/public/design-system/icons/chart.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M3 19h18"></path>
+ <path d="M5 19V11l3-2 3 2v8"></path>
+ <path d="M13 19V7l3-2 3 2v12"></path>
+ <path d="M5 19V13"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/clock.svg b/frontend/public/design-system/icons/clock.svg
new file mode 100644
index 0000000..42a244b
--- /dev/null
+++ b/frontend/public/design-system/icons/clock.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <circle cx="12" cy="12" r="9"></circle>
+ <path d="M12 7v5l3 2"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/command.svg b/frontend/public/design-system/icons/command.svg
new file mode 100644
index 0000000..19dd2af
--- /dev/null
+++ b/frontend/public/design-system/icons/command.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M5 17l5-5-5-5"></path>
+ <path d="M12 19h7"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/dollar.svg b/frontend/public/design-system/icons/dollar.svg
new file mode 100644
index 0000000..83e4a40
--- /dev/null
+++ b/frontend/public/design-system/icons/dollar.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M12 3v18"></path>
+ <path d="M17 7H10a3 3 0 100 6h4a3 3 0 110 6H6"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/folder.svg b/frontend/public/design-system/icons/folder.svg
new file mode 100644
index 0000000..cb8ea41
--- /dev/null
+++ b/frontend/public/design-system/icons/folder.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M4 4h8l2 3h6v11a2 2 0 01-2 2H4a2 2 0 01-2-2V6a2 2 0 012-2z" transform="translate(1 0)"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/ledger.svg b/frontend/public/design-system/icons/ledger.svg
new file mode 100644
index 0000000..989e7a8
--- /dev/null
+++ b/frontend/public/design-system/icons/ledger.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M4 7h16"></path>
+ <path d="M4 12h16"></path>
+ <path d="M4 17h10"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/pulse.svg b/frontend/public/design-system/icons/pulse.svg
new file mode 100644
index 0000000..bfa6e5b
--- /dev/null
+++ b/frontend/public/design-system/icons/pulse.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M3 12h4l3-8 4 16 3-8h4"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/search.svg b/frontend/public/design-system/icons/search.svg
new file mode 100644
index 0000000..4c561f8
--- /dev/null
+++ b/frontend/public/design-system/icons/search.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <circle cx="11" cy="11" r="6"></circle>
+ <path d="M15.5 15.5L20 20"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/terminal.svg b/frontend/public/design-system/icons/terminal.svg
new file mode 100644
index 0000000..a36c7bc
--- /dev/null
+++ b/frontend/public/design-system/icons/terminal.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <rect x="3" y="4" width="18" height="14" rx="1"></rect>
+ <path d="M3 8h18"></path>
+ <path d="M8 20h8"></path>
+ <path d="M12 18v2"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/user.svg b/frontend/public/design-system/icons/user.svg
new file mode 100644
index 0000000..45b7766
--- /dev/null
+++ b/frontend/public/design-system/icons/user.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <circle cx="12" cy="8" r="4"></circle>
+ <path d="M4 21c0-4 4-7 8-7s8 3 8 7"></path>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/icons/window.svg b/frontend/public/design-system/icons/window.svg
new file mode 100644
index 0000000..1c37c86
--- /dev/null
+++ b/frontend/public/design-system/icons/window.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
+ <rect x="3" y="5" width="18" height="14" rx="1"></rect>
+ <path d="M3 9h18"></path>
+ <circle cx="7" cy="7" r=".5" fill="currentColor"></circle>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/logo-monogram.svg b/frontend/public/design-system/logo-monogram.svg
new file mode 100644
index 0000000..ddb4c58
--- /dev/null
+++ b/frontend/public/design-system/logo-monogram.svg
@@ -0,0 +1,23 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
+ <defs>
+ <linearGradient id="brass" x1="0" y1="0" x2="0" y2="1">
+ <stop offset="0%" stop-color="#DCC79E"></stop>
+ <stop offset="55%" stop-color="#C2AA7A"></stop>
+ <stop offset="100%" stop-color="#8F7A50"></stop>
+ </linearGradient>
+ </defs>
+
+ <circle cx="100" cy="100" r="92" fill="none" stroke="url(#brass)" stroke-width="2"></circle>
+ <circle cx="100" cy="100" r="86" fill="none" stroke="url(#brass)" stroke-width="0.75" opacity="0.55"></circle>
+
+ <g fill="url(#brass)" font-family="&#39;EB Garamond&#39;, &#39;Source Serif Pro&#39;, Georgia, serif" font-style="italic" font-weight="500" text-anchor="middle">
+ <text x="100" y="128" font-size="110" letter-spacing="-6">TH</text>
+ </g>
+
+ <g stroke="url(#brass)" stroke-width="1.2">
+ <line x1="100" y1="6" x2="100" y2="14"></line>
+ <line x1="100" y1="186" x2="100" y2="194"></line>
+ <line x1="6" y1="100" x2="14" y2="100"></line>
+ <line x1="186" y1="100" x2="194" y2="100"></line>
+ </g>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/logo-wordmark.svg b/frontend/public/design-system/logo-wordmark.svg
new file mode 100644
index 0000000..2449e19
--- /dev/null
+++ b/frontend/public/design-system/logo-wordmark.svg
@@ -0,0 +1,24 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 120" width="560" height="120">
+ <defs>
+ <linearGradient id="brass2" x1="0" y1="0" x2="0" y2="1">
+ <stop offset="0%" stop-color="#DCC79E"></stop>
+ <stop offset="55%" stop-color="#C2AA7A"></stop>
+ <stop offset="100%" stop-color="#8F7A50"></stop>
+ </linearGradient>
+ </defs>
+
+ <g transform="translate(60 60)">
+ <circle r="46" fill="none" stroke="url(#brass2)" stroke-width="1.4"></circle>
+ <circle r="42" fill="none" stroke="url(#brass2)" stroke-width="0.5" opacity="0.55"></circle>
+ <text x="0" y="14" font-family="&#39;EB Garamond&#39;,&#39;Source Serif Pro&#39;,Georgia,serif" font-style="italic" font-weight="500" font-size="56" letter-spacing="-3" text-anchor="middle" fill="url(#brass2)">TH</text>
+ </g>
+
+ <g transform="translate(135 60)">
+ <g font-family="&#39;EB Garamond&#39;,Georgia,serif" font-size="36" fill="#F2ECDC">
+ <text x="0" y="-4" font-weight="500">Thuy</text>
+ <text x="78" y="-4" font-weight="400" font-style="italic" fill="#C2AA7A">(Tyler)</text>
+ <text x="186" y="-4" font-weight="500">Hoang</text>
+ </g>
+ <text x="2" y="26" font-family="&#39;IBM Plex Sans&#39;,sans-serif" font-weight="500" font-size="11" fill="#8E8676" letter-spacing="3.2">FINANCE · ANALYTICS · CFA LEVEL I CANDIDATE</text>
+ </g>
+</svg> \ No newline at end of file
diff --git a/frontend/public/design-system/prism.css b/frontend/public/design-system/prism.css
new file mode 100644
index 0000000..f4bca93
--- /dev/null
+++ b/frontend/public/design-system/prism.css
@@ -0,0 +1,365 @@
+/* Prism dashboard — kit-specific layout (tokens from ../../colors_and_type.css) */
+
+*, *::before, *::after { box-sizing: border-box; }
+html, body { margin: 0; background: var(--ink-0); height: 100%; }
+.prism-app {
+ display: grid;
+ grid-template-columns: 256px 1fr;
+ min-height: 100vh;
+}
+
+/* ----- Sidebar ----- */
+.psm-side {
+ background: var(--ink-1);
+ border-right: 1px solid var(--line-1);
+ display: flex; flex-direction: column;
+ position: sticky; top: 0; height: 100vh;
+ overflow-y: auto;
+}
+.psm-brand {
+ padding: var(--sp-5) var(--sp-5) var(--sp-4);
+ border-bottom: 1px solid var(--line-1);
+ display: flex; align-items: center; gap: var(--sp-3);
+}
+.psm-brand .mark {
+ width: 32px; height: 32px; border-radius: 50%;
+ border: 1px solid var(--brass);
+ display: flex; align-items: center; justify-content: center;
+ font-family: var(--font-display); font-style: italic; font-size: 18px;
+ color: var(--brass); letter-spacing: -0.05em;
+}
+.psm-brand .meta { display: flex; flex-direction: column; gap: 2px; }
+.psm-brand .name {
+ font-family: var(--font-display); font-size: 20px; color: var(--fg-1);
+ font-weight: 500; letter-spacing: -0.01em; line-height: 1;
+}
+.psm-brand .sub {
+ font-family: var(--font-mono); font-size: 10px;
+ color: var(--fg-3); letter-spacing: 0.18em; text-transform: uppercase;
+}
+
+.psm-section {
+ padding: var(--sp-5) var(--sp-4) var(--sp-2);
+ font-family: var(--font-sans); font-size: var(--fs-12);
+ font-weight: 600; text-transform: uppercase; letter-spacing: var(--tr-wider);
+ color: var(--fg-3);
+}
+.psm-nav { display: flex; flex-direction: column; }
+.psm-nav a {
+ display: flex; align-items: center; gap: var(--sp-3);
+ padding: 8px var(--sp-4);
+ font-family: var(--font-sans); font-size: var(--fs-14);
+ color: var(--fg-2); text-decoration: none; border-bottom: none;
+ border-left: 2px solid transparent;
+ cursor: pointer;
+}
+.psm-nav a:hover { background: var(--ink-2); color: var(--fg-1); }
+.psm-nav a.active {
+ background: var(--ink-2); color: var(--fg-1);
+ border-left-color: var(--brass);
+}
+.psm-nav a .ico {
+ width: 16px; height: 16px; background: currentColor;
+ -webkit-mask-size: contain; mask-size: contain;
+ -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
+ -webkit-mask-position: center; mask-position: center;
+ opacity: 0.7;
+}
+
+.psm-watch {
+ margin: 0 var(--sp-4);
+ border-top: 1px solid var(--line-1);
+}
+.psm-watch-row {
+ display: grid;
+ grid-template-columns: 1fr auto auto;
+ gap: var(--sp-2);
+ align-items: baseline;
+ padding: 8px 0;
+ border-bottom: 1px solid var(--line-1);
+ cursor: pointer;
+}
+.psm-watch-row:hover { background: rgba(194,170,122,0.04); }
+.psm-watch-row .sym { font-family: var(--font-sans); font-size: var(--fs-14); font-weight: 500; color: var(--fg-1); }
+.psm-watch-row .px { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-13); color: var(--fg-1); text-align: right; }
+.psm-watch-row .chg { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-12); text-align: right; min-width: 56px; }
+.pos { color: var(--positive); }
+.neg { color: var(--negative); }
+
+/* ----- Main column ----- */
+.psm-main {
+ display: flex; flex-direction: column;
+ min-width: 0;
+}
+
+/* Top bar */
+.psm-top {
+ background: var(--ink-0);
+ border-bottom: 1px solid var(--line-1);
+ padding: var(--sp-3) var(--sp-6);
+ display: flex; align-items: center; gap: var(--sp-4);
+ position: sticky; top: 0; z-index: 5;
+}
+.psm-search {
+ flex: 1; max-width: 480px;
+ display: flex; align-items: center; gap: var(--sp-2);
+ background: var(--ink-2); border: 1px solid var(--line-2);
+ border-radius: var(--r-2); padding: 8px var(--sp-3);
+}
+.psm-search:focus-within { border-color: var(--brass); }
+.psm-search input {
+ flex: 1; background: transparent; border: none; outline: none;
+ font-family: var(--font-mono); font-size: var(--fs-13); color: var(--fg-1);
+}
+.psm-search input::placeholder { color: var(--fg-3); }
+.psm-search .kbd {
+ font-family: var(--font-mono); font-size: var(--fs-12);
+ color: var(--fg-3); border: 1px solid var(--line-2);
+ padding: 1px 6px; border-radius: var(--r-1);
+ background: var(--ink-1);
+}
+.psm-clock {
+ font-family: var(--font-mono); font-size: var(--fs-13);
+ color: var(--fg-2); display: flex; gap: var(--sp-3); align-items: center;
+}
+.psm-clock .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--positive); box-shadow: 0 0 8px var(--positive); }
+.psm-account {
+ display: flex; align-items: center; gap: 8px;
+ padding: 6px 12px; border: 1px solid var(--line-2); border-radius: var(--r-full);
+ font-family: var(--font-sans); font-size: var(--fs-13); color: var(--fg-1);
+}
+.psm-account .avatar {
+ width: 22px; height: 22px; border-radius: 50%;
+ background: var(--brass); color: var(--brass-ink);
+ display: flex; align-items: center; justify-content: center;
+ font-family: var(--font-display); font-style: italic; font-size: 12px; font-weight: 500;
+}
+
+/* Content area */
+.psm-content { padding: var(--sp-6) var(--sp-6) var(--sp-9); display: flex; flex-direction: column; gap: var(--sp-5); }
+
+.psm-ticker-head {
+ display: grid;
+ grid-template-columns: auto 1fr auto;
+ gap: var(--sp-5);
+ align-items: end;
+ padding-bottom: var(--sp-4);
+ border-bottom: 1px solid var(--line-1);
+}
+.psm-ticker-head .left { display: flex; align-items: baseline; gap: var(--sp-4); }
+.psm-ticker-head .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-ticker-head .name {
+ font-family: var(--font-display); font-style: italic;
+ font-size: var(--fs-24); color: var(--fg-2); font-weight: 400;
+}
+.psm-ticker-head .sector {
+ font-family: var(--font-sans); font-size: var(--fs-12);
+ text-transform: uppercase; letter-spacing: var(--tr-wider);
+ color: var(--brass); font-weight: 600;
+ display: block; margin-bottom: var(--sp-2);
+}
+.psm-ticker-head .px-block {
+ display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
+}
+.psm-ticker-head .px {
+ font-family: var(--font-mono); font-variant-numeric: tabular-nums;
+ font-size: var(--fs-48); color: var(--fg-1); line-height: 1; font-weight: 500;
+}
+.psm-ticker-head .chg {
+ font-family: var(--font-mono); font-variant-numeric: tabular-nums;
+ font-size: var(--fs-16);
+}
+
+.psm-range {
+ font-family: var(--font-mono); font-size: var(--fs-12);
+ color: var(--fg-3); display: flex; gap: var(--sp-4);
+}
+.psm-range .marker {
+ position: relative;
+ width: 140px; height: 4px;
+ background: var(--ink-3); border-radius: 999px;
+}
+.psm-range .marker::after {
+ content: ""; position: absolute; top: -3px;
+ width: 2px; height: 10px; background: var(--brass);
+}
+
+/* KPI strip */
+.psm-kpis {
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ border: 1px solid var(--line-1);
+ border-radius: var(--r-3);
+ background: var(--ink-1);
+ overflow: hidden;
+}
+.psm-kpi {
+ padding: var(--sp-4) var(--sp-5);
+ border-right: 1px solid var(--line-1);
+ display: flex; flex-direction: column; gap: 4px;
+}
+.psm-kpi:last-child { border-right: none; }
+.psm-kpi .k {
+ font-family: var(--font-sans); font-size: var(--fs-12);
+ text-transform: uppercase; letter-spacing: var(--tr-wider);
+ color: var(--fg-3); font-weight: 600;
+}
+.psm-kpi .v {
+ font-family: var(--font-mono); font-variant-numeric: tabular-nums;
+ font-size: var(--fs-24); color: var(--fg-1); font-weight: 500;
+}
+.psm-kpi .sub { font-family: var(--font-mono); font-size: var(--fs-12); color: var(--fg-3); }
+
+/* Two-column grid below */
+.psm-grid {
+ display: grid;
+ grid-template-columns: 2fr 1fr;
+ gap: var(--sp-5);
+}
+.psm-card {
+ background: var(--ink-1);
+ border: 1px solid var(--line-1);
+ border-radius: var(--r-3);
+ padding: var(--sp-5);
+ display: flex; flex-direction: column; gap: var(--sp-3);
+ box-shadow: var(--shadow-1);
+}
+.psm-card-head {
+ display: flex; justify-content: space-between; align-items: baseline;
+ margin-bottom: var(--sp-2);
+}
+.psm-card-head h3 {
+ font-family: var(--font-display); font-size: var(--fs-24);
+ color: var(--fg-1); font-weight: 500; margin: 0;
+}
+.psm-card-head .eyebrow {
+ font-family: var(--font-sans); font-size: var(--fs-12);
+ text-transform: uppercase; letter-spacing: var(--tr-wider);
+ color: var(--fg-3); font-weight: 600;
+}
+
+.psm-tabs {
+ display: flex; gap: 4px;
+ border: 1px solid var(--line-2);
+ background: var(--ink-2);
+ border-radius: var(--r-1);
+ padding: 2px;
+}
+.psm-tab {
+ font-family: var(--font-mono); font-size: var(--fs-12);
+ background: transparent; border: none; color: var(--fg-3);
+ padding: 4px 10px; cursor: pointer; border-radius: var(--r-1);
+}
+.psm-tab.active { background: var(--ink-3); color: var(--fg-1); }
+.psm-tab:hover:not(.active) { color: var(--fg-1); }
+
+/* Chart placeholder */
+.psm-chart {
+ height: 260px; position: relative;
+ background: var(--ink-0);
+ border: 1px solid var(--line-1);
+ border-radius: var(--r-2);
+ overflow: hidden;
+}
+
+/* Quote table */
+.psm-table { width: 100%; border-collapse: collapse; }
+.psm-table th {
+ font-family: var(--font-sans); font-size: var(--fs-12);
+ font-weight: 600; color: var(--fg-3);
+ text-transform: uppercase; letter-spacing: var(--tr-wide);
+ text-align: left; padding: 8px var(--sp-3);
+ border-bottom: 1px solid var(--line-2);
+}
+.psm-table th.r, .psm-table td.r { text-align: right; }
+.psm-table td {
+ font-family: var(--font-mono); font-variant-numeric: tabular-nums;
+ font-size: var(--fs-14); color: var(--fg-1);
+ padding: 10px var(--sp-3);
+ border-bottom: 1px solid var(--line-1);
+}
+.psm-table td.lbl { font-family: var(--font-sans); color: var(--fg-1); font-weight: 500; }
+.psm-table tbody tr:hover { background: rgba(194,170,122,0.04); }
+
+/* Valuation strip */
+.psm-val {
+ display: flex; flex-direction: column; gap: var(--sp-3);
+}
+.psm-val-row {
+ display: grid;
+ grid-template-columns: 1fr auto;
+ align-items: center;
+ padding: var(--sp-3) 0;
+ border-bottom: 1px solid var(--line-1);
+}
+.psm-val-row:last-child { border-bottom: none; }
+.psm-val-row .label {
+ font-family: var(--font-sans); font-size: var(--fs-14); color: var(--fg-2);
+}
+.psm-val-row .num {
+ font-family: var(--font-mono); font-variant-numeric: tabular-nums;
+ font-size: var(--fs-18); color: var(--fg-1); font-weight: 500;
+}
+.psm-verdict {
+ margin-top: var(--sp-3);
+ padding: var(--sp-3) var(--sp-4);
+ border: 1px solid rgba(79,140,94,0.35);
+ background: var(--positive-bg);
+ border-radius: var(--r-2);
+ font-family: var(--font-sans); font-size: var(--fs-14);
+ color: var(--positive);
+ display: flex; justify-content: space-between; align-items: baseline;
+}
+.psm-verdict .v {
+ font-family: var(--font-display); font-style: italic;
+ color: var(--fg-1); font-size: var(--fs-18);
+}
+
+/* Filings list */
+.psm-filing {
+ display: grid;
+ grid-template-columns: 64px 1fr auto;
+ gap: var(--sp-3);
+ align-items: center;
+ padding: 10px 0;
+ border-bottom: 1px solid var(--line-1);
+}
+.psm-filing:last-child { border-bottom: none; }
+.psm-filing .type {
+ font-family: var(--font-mono); font-size: var(--fs-12);
+ color: var(--brass); background: rgba(194,170,122,0.08);
+ border: 1px solid rgba(194,170,122,0.3);
+ padding: 2px 6px; border-radius: var(--r-1);
+ text-align: center;
+}
+.psm-filing .ttl { font-family: var(--font-sans); font-size: var(--fs-13); color: var(--fg-1); }
+.psm-filing .date { font-family: var(--font-mono); font-size: var(--fs-12); color: var(--fg-3); }
+
+/* Insider rows */
+.psm-insider {
+ display: grid;
+ grid-template-columns: 1fr auto auto;
+ gap: var(--sp-3);
+ align-items: center;
+ padding: var(--sp-3) 0;
+ border-bottom: 1px solid var(--line-1);
+}
+.psm-insider:last-child { border-bottom: none; }
+.psm-insider .who { display: flex; flex-direction: column; gap: 2px; }
+.psm-insider .name { font-family: var(--font-sans); font-size: var(--fs-14); color: var(--fg-1); }
+.psm-insider .role { font-family: var(--font-sans); font-size: var(--fs-12); color: var(--fg-3); }
+.psm-insider .pill {
+ font-family: var(--font-mono); font-size: var(--fs-12);
+ padding: 2px 8px; border-radius: var(--r-1);
+}
+.psm-insider .pill.buy { background: var(--positive-bg); color: var(--positive); border: 1px solid rgba(79,140,94,0.35); }
+.psm-insider .pill.sell { background: var(--negative-bg); color: var(--negative); border: 1px solid rgba(181,73,75,0.35); }
+.psm-insider .val {
+ font-family: var(--font-mono); font-variant-numeric: tabular-nums;
+ font-size: var(--fs-14); color: var(--fg-1); text-align: right;
+ min-width: 96px;
+}