soldi design system — "closer v2"
Authoritative design language for the app, derived from the closer — v2
prototype at reference/closer/public/v2/index.html. This replaces the
current Robinhood-green theme. Migration is breaking for every themed element;
do it as one foundation slice, then build new pages on top of it.
Prototype tagline (the product thesis): "The trading floor for real estate leads. Auction-priced exclusivity. AI-powered comps in under three seconds. One tab replaces PropStream, REsimpli, and Follow Up Boss."
1. Color palette
Editorial / metallic dark. Map into the Tailwind v4 @theme block in
src/index.css as the single source of truth, then mirror into :root for raw
var() consumers.
Neutrals
|-|-|-|
| token | hex | use |
| --bg | #0B0D0E | page background |
| --bg-elev | #0F1214 | elevated surfaces, drawer, insets |
| --surface | #161A1D | cards |
| --surface-2 | #1E2327 | pills, buttons, inset rows |
| --surface-3 | #262C31 | active tab, hover surface |
| --border | #22272B | default border |
| --border-bright | #333A40 | hover / focus border |
| --border-hot | #504437 | alert border |
Text tiers
|-|-|-|
| --text | #F1EDE8 | primary (warm off-white) |
| --text-dim | #A7ADB3 | secondary |
| --text-mute | #6B7278 | labels |
| --text-faint | #4A5056 | disabled / faint |
Semantic (the metallic palette — locked 2026-04-22)
|-|-|-|
| --bull | #4FBA8B | positive / primary action / up (replaces old green accent) |
| --bull-dim | #2F7D5E | tinted bull |
| --bear | #E6675A | loss / danger / down |
| --warn | #E8A94A | caution / time pressure |
| --hot | #D97738 | urgency / alert / under-contract |
| --accent | #A392E8 | AI / special / third-party (lavender) |
| --accent-dim | #574A88 | tinted accent |
| --gold | #C9A878 | premium / assigned / closed |
| --gold-dim | #8E7650 | tinted gold |
Tinted variants use color-mix(in srgb, var(--x) 15%, transparent).
Semantic remap from the old theme
The old theme overloaded one green --accent for everything. Split it by meaning:
|-|-|
| old | new |
| --accent #00D4AA (primary/positive) | --bull #4FBA8B |
| --danger #FF4757 | --bear #E6675A |
| --warning #FFA502 | --warn #E8A94A |
| --success #2ED573 | --bull |
| --gold #FFD700 | --gold #C9A878 |
| (new) AI / special | --accent #A392E8 |
| (new) urgency | --hot #D97738 |
First pass: find-replace #00D4AA → #4FBA8B. Second pass: re-classify each use —
some greens are really --warn (time pressure) or --hot (urgency).
2. Typography
Load via Google Fonts (already in the prototype <link>):
Fraunces (opsz 9..144 + SOFT axis), Instrument Serif, Hanken Grotesk,
JetBrains Mono.
|-|-|-|
| token | family | use |
| --font-wordmark | Instrument Serif (italic) | the "closer" wordmark, 30px |
| --font-display | Fraunces (optical sizing) | section headings (h2 30px italic), KPI numbers (26px) |
| --font-body | Hanken Grotesk | body, nav, labels (13–14px) |
| --font-mono | JetBrains Mono | currency, timestamps, counts (tabular-nums) |
- Card / lead addresses: Instrument Serif 19px (hero 32px).
- Micro labels (
.lbl,.k,.micro): JetBrains Mono, 11px, uppercase,letter-spacing: .08em. .tnumutility →font-feature-settings: "tnum"for aligned numerics.- Keep
--font-bodymapped to Hanken Grotesk; retire Inter/Plus Jakarta.
3. Radius, spacing, shadow, grid
- Radius:
--radius 10px(cards/pills),--radius-sm 6px(badges),--radius-lg 16px(hero, drawer, filters). - Gaps: 20px page grid · 14px card grid · 10px hero grid · 6px pill rows.
--shadow-lift: 0 1px 0 rgba(255,255,255,.02) inset, 0 16px 40px -24px rgba(0,0,0,.8).- Card hover glow:
0 0 0 1px <bull-tint>, 0 12px 32px -20px rgba(79,186,139,.35). - Decorative grid wash (net-new, global, zero JS):
body::before, 56×56pxrepeating-linear-gradientat opacity .35 with a radialmask-imagethat fades top→bottom. Adds the "terminal" texture.
4. Signature components
- Buttons:
.btn(surface-2 + border-bright, secondary) ·.btn.primary(bull bg, dark text#062315) ·.btn.ghost(transparent + outline) ·.btn.danger(bear text). Refactor today's single.btn-*set into this variant system. - Quality circle (
.qscore): 90pxconic-gradient(var(--bull) 0 calc(var(--score)*1%), …)with an inner surface ring; number in Fraunces 28px. Drives the lead quality badge. - Pills / chips: distress, hot, equity, age — surface-2, mono 11.5px, 999px radius.
- Sparkline: SVG path from the
bids[]series (bull line + gradient fill + last-point dot). Compute from real bid history, not random jitter. - Ticker (
LiveTicker): 28px strip, marquee 72s, mono,--bull/--bear/--warn. Already exists — restyle only. - Lead drawer: 560px right slide-in (
translateX(100%)→0, cubic-bezier .32s), dark gradient bid-console, order-book table (4-col grid, per-row--wgradient fill,.livehighlight), tabs (Bid / Comps / Seller / Activity). - Animations:
pulse(ticker dot),price-flash(bid update),urgent-pulse(countdown < 600s),revealUp(staggered page-load, use sparingly on hero + top grids).
5. Migration checklist (foundation slice)
- Rewrite
@theme+:rootinsrc/index.csswith the tokens above; add font<link>toindex.html. - Add the grid-wash
body::before,--shadow-lift, radius/spacing tokens, and the keyframes. - Re-baseline component classes (
.btn*,.card, pills,.qscore, headings) to the new variant system. - Sweep pages (Marketplace, LeadDetail, Portfolio, TopNav, LiveTicker) replacing
accent→bulland re-classifying semantic colors. - Restyle
TopNavbrand to Instrument Serif "closer" wordmark + bull.dot; keep router intact. - Visual-regression by screenshot against the prototype panel-by-panel.
Keep auth/session, routing, and the working marketplace+bidding logic intact — this slice is paint, not plumbing.