The first version of Avo's UI was built with a teal and electric blue palette on dark backgrounds. It looked like every other fintech SaaS dashboard from 2023. We deleted all of it and replaced it with a strict black-and-white chrome system. The product got noticeably better.
What Was Wrong with Color
The original palette used a bright teal as a primary accent, electric blue for interactive states, amber for warnings, and green for positive signals. This is a reasonable color system for a generic application. For a financial data product, it created two specific problems.
First: color overload. Financial data is inherently colorful. Red means down, green means up, candles have bodies and wicks, heatmaps use continuous color scales, correlation matrices use diverging palettes. When the UI chrome also uses bright colors, the data colors compete with the interface colors. The user's eye cannot distinguish “this color means something in the data” from “this color is just decoration.”
Second: the teal brand color was everywhere. Every button, every badge, every link, every hover state used teal. It felt energetic in isolation and exhausting in a session. Users who spend hours in a financial terminal do not want a product that is constantly drawing attention to its own chrome.
The B&W Chrome Principle
The principle we settled on: the interface chrome is black and white. Data is allowed to have color. The chrome recedes so the data can speak.
In practice this means:
- →Backgrounds: pure near-black (#0B0E14, #141720) or pure white. No teal backgrounds.
- →Borders: a single near-black border color (#1E2230). No colored borders.
- →Text: zinc-900 for headings, zinc-600 for body, zinc-400/500 for secondary. No colored text in the chrome.
- →Buttons: zinc-900 background with white text for primary. White background with zinc-900 text for secondary. No teal buttons.
- →Status indicators: the only remaining use of color. Green for positive, red for negative, amber for warning. These are semantic data colors, not brand colors.
The teal color was not deleted entirely. It survived as a subtle border treatment on one component: the InlineNewsletterCta uses a border-[#0FB8A0]/30 to add just enough distinction from the surrounding zinc borders to signal that it is a conversion element, not content. That single use of color does more work than the previous system where teal was everywhere.
Get weekly intelligence delivered to your inbox
Curated signals, regime shifts, and anomaly highlights from Avo Intelligence. Every Monday. Free.
Tailwind Token Strategy
Our Tailwind configuration defines a small set of semantic tokens instead of using Tailwind's full color palette ad-hoc:
// tailwind.config.ts
const config = {
theme: {
extend: {
colors: {
// Surface hierarchy
"surface-base": "#0B0E14", // deepest background
"surface-raised": "#141720", // cards, modals
"surface-overlay": "#1A1F2E", // tooltips, popovers
// Border
"border-default": "#1E2230", // single border color for all chrome
// Text hierarchy (zinc-based)
"text-primary": "#E2E8F0", // headings on dark
"text-secondary": "#94a3b8", // body on dark
"text-muted": "#64748B", // labels, metadata
// Semantic colors (data only, not chrome)
"signal-up": "#22c55e", // green
"signal-down": "#ef4444", // red
"signal-warning": "#f59e0b", // amber
"signal-neutral": "#94a3b8", // zinc
},
},
},
};The separation between surface, border, text, and signal tokens made the system mechanical to apply. Any new component has exactly four decisions to make: which surface level am I on, what border do I need, which text weight, and do I have any semantic data to display. There is no “what color should this be” question.
Typography: Geist
We switched to Geist as the primary typeface. Geist is Vercel's typeface, designed for technical interfaces: high x-height, excellent legibility at small sizes, and a technical quality that signals precision without being clinical.
The combination of Geist at small sizes (12-14px for data labels) on near-black backgrounds creates a terminal-quality aesthetic. Financial professionals who use Bloomberg and Reuters terminals recognize this quality. It signals that the product was built for serious work, not for marketing screenshots.
// app/layout.tsx
import { GeistSans } from "geist/font/sans";
import { GeistMono } from "geist/font/mono";
// GeistSans for all UI text
// GeistMono for numeric data, code, ticker symbols
// Using CSS custom properties:
// --font-geist-sans and --font-geist-mono
// These flow through Tailwind's font-sans and font-mono utilities4px Radius Rule
Every rounded corner in the UI uses exactly 4px radius (rounded in Tailwind). Nothing uses rounded-xl,rounded-2xl, or fully circular corners except for pills (tags, badges) which use rounded-full.
This was a deliberate pushback against the large-radius trend in consumer SaaS design. 16-24px radius on large cards creates a soft, playful feel appropriate for consumer apps. Financial data products should feel precise and rectilinear. The 4px rule maintains crispness without feeling harsh.
Glassmorphism Without the Gimmicks
The redesigned hero and several overlay components use a glass effect: a slightly translucent surface with a subtle border and a background-blur. This is glassmorphism, which has a bad reputation because it is often overused decoratively.
Our implementation is restrained: glass is used only on elements that float above a moving background (the mesh gradient hero) or on modal overlays where showing depth is semantically meaningful. It is never used on static content cards or data displays.
/* Glass component: used sparingly on floating elements only */
.glass-card {
background: rgba(20, 23, 32, 0.7);
backdrop-filter: blur(12px) saturate(140%);
-webkit-backdrop-filter: blur(12px) saturate(140%);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 4px;
}
/* NOT used on: data cards, table rows, stat displays */
/* USED on: hero floating panels, modal overlays, command palette */What We Gained
- →Data visualization now has full control of the color space. Charts, heatmaps, and correlation matrices are more readable because the chrome does not compete.
- →Component development became faster. No color decisions means fewer debates. A new component is built in the zinc/border-default/signal token system and it matches everything else automatically.
- →The product feels more authoritative. B&W chrome signals precision. Color-heavy fintech UIs often feel like consumer apps dressed up as professional tools. Ours reads as a professional tool.
- →Accessibility improved. High-contrast zinc text on near-black surfaces passes WCAG AA without adjustments. Color-only status indicators are supplemented with text labels.
The One Thing We Kept
The hero gradient mesh. A subtle animated gradient of near-blacks and dark slates behind the hero text adds depth without color. It is the visual anchor that makes the above-the-fold section feel alive without reintroducing the color noise we worked to remove.
It runs as a CSS animation on a layered background gradient. No JavaScript, no canvas, no Three.js. The performance cost is effectively zero.
Need similar work shipped?
We build design systems and production Next.js applications for technical products. If you need a serious UI built right, we can help.
Start a Project →