A warmer Bankrate
The rebrand introduced a new logo and wordmark, warmed the existing color palette, and added hand-drawn squiggles to make the brand feel more human.












A multi-design system for Bankrate’s products, brands, and agents.
In the era of AI, the C-suite believes it can build anything and everything. So Bankrate was becoming a little bit of everything.
Treasury was designed for Bankrate’s marketing website. Ledger is the new and shiny system, extending the framework beyond the website to Bankrate’s existing SaaS products and those yet to exist.
New leadership usually brings a reset. At Bankrate, that meant rethinking the brand, tech stack, and how teams could ship faster.
Evolving the system involved:
All of it had to ship in 30 days: the rebrand translated into Ledger, the shadcn registries released to product teams, and enough of the system in place for them to start building.
This was a pressure-cooker test for AI: can it deliver this quickly? The answer is yes, if you don’t care about quality.
I flipped Treasury’s foundations into the rebrand within 24 hours without AI. Treasury was a Tailwind theme that expressed Bankrate’s design decisions. The swap preserved intent instead of merely replacing one string with another.
For example, because the colors were organized into perceptually uniform scales, I could swap out the hex values in the Tailwind config. A heading still used gray 900, keeping the same visual weight and contrast even though the hex value behind it had changed.
Across 1,000+ components and 1,000+ pages, the flip looked almost uneventful. Nothing broke.
Refactoring Classy into Treasury paid off. The systematic decisions I made years ago carried the system through the rebrand without another rebuild.
When building Treasury, we chose not to use semantic variables. Instead, we worked directly from Tailwind’s primitive variables: blue-600, gray-400, orange-900, and so on.
Shadcn comes with a base set of variables built into its components, so adopting it meant retrofitting them to express Bankrate’s design language. Variables sound fun until you realize they can become a bottomless pit. Every interaction state, component-specific color, and one-off design becomes, surprisingly, like 100 variables to maintain.
I spent a few days building a sandbox of UI components and templates to see how far the base shadcn variables could stretch across different interfaces.
The base shadcn variables covered about 95% of what we needed. I didn’t love every aesthetic decision, but changing them would have added variables and maintenance without making the interface work any better. I handled the remaining gaps inside components with mixins and opacity, which I’d largely avoided in Treasury.
Ledger’s button used one semantic variable. The hover state modified that value with an opacity mixin, and I left out a separate active state. The disabled state targeted the primitive variable gray-600 in the component code, so it didn’t need another semantic variable.
The tradeoff was less visual affordance, but the button stayed within shadcn’s base variable set.
Marketing used Tailwind’s primitive variables (such as blue-600) the same way we did in Treasury. These layouts are more expressive and don’t map cleanly to shadcn’s base variables.
| Use semantic variables for | Use primitive variables for |
|---|---|
| White-label products | Marketing pages |
| Reusable components | Temporary sections |
| Light and dark themes | One-off compositions |
White-labeling requires discipline. I made the design and engineering decisions up front so teams could ship without a designer. Customization is possible, but once teams start debating design choices, white-labeling stops saving time.
Not everything was fully built for Ledger’s release because that’s quite literally impossible; no one knows what these new initiatives will require. But I did set up the API to anticipate those changes when they come.
To keep Ledger “canonical” across products, I structured the API with:
That structure gave teams room to use what Ledger already provided or add what their product needed without creating conflicts or overriding the core.
Design systems are usually for designers and engineers. Now that Ledger is a registry, it is accessible to engineers, product managers, the C-suite, or even an accountant. Now the consumer is their agent.
No two agents run exactly the same way. Even my agents can seem to change personality depending on the day of the week. Agents show up in different forms: IDE assistants, CLI agents, and wrappers like v0 or Figma AI. Even huge cloud models compete to stay in the news cycle, releasing updates almost every 3 weeks.
In .md files, I’ve documented decisions designers and engineers make unconsciously. That meant consciously thinking about what I do unconsciously, and it kind of broke my brain.
Agent testing is difficult. My agents have 3+ years of training through daily design-system work. Establishing a control and identifying the cause is complicated by changes to the underlying models, agent mood swings, and the challenge of isolating an agent.
At the time of this writing, Ledger is about 2 months old. Bringing the rebrand and new tech stack together in Ledger took about 30 days. I built the shadcn registry in 1 week so product teams and engineers could start implementing the rebrand before the deadline.
Is that crazy work?… Uh, yes.
Future products and agent behavior remain unknown. I hope Ledger helps product teams ship faster without recreating the same components. Over time, we’ll see whether shadcn will hold up as the distribution model for a multi-design system.
Spoiler: It won’t.